CMake issueshttps://gitlab.kitware.com/cmake/cmake/-/issues2024-03-05T06:02:25-05:00https://gitlab.kitware.com/cmake/cmake/-/issues/25731CMake does not support C++20 modules with clang-cl.exe2024-03-05T06:02:25-05:00Sharadh RajaramanCMake does not support C++20 modules with clang-cl.exeSupplying `CMAKE_CXX_COMPILER=clang-cl` with a target containing `FILE_SET CXX_MODULES` does not work, and during configuration, CMake errors with:
```
CMake Error in CMakeLists.txt:
The target named "main" has C++ sources that may us...Supplying `CMAKE_CXX_COMPILER=clang-cl` with a target containing `FILE_SET CXX_MODULES` does not work, and during configuration, CMake errors with:
```
CMake Error in CMakeLists.txt:
The target named "main" has C++ sources that may use modules, but the
compiler does not provide a way to discover the import graph dependencies.
See the cmake-cxxmodules(7) manual for details. Use the
CMAKE_CXX_SCAN_FOR_MODULES variable to enable or disable scanning.
```
`clang-cl.exe` is in fact _exactly_ (read: bit-for-bit equal, and therefore have equal file checksums) the same binary as `clang.exe` in the official LLVM distribution for Windows, with only differing file names. It is able to [forward arguments to the GNU-style driver with `/clang:`](https://github.com/llvm/llvm-project/blob/051e910b8b6c59fc94d019fa01ae4507b1c81498/clang/docs/UsersManual.rst#L4397), and therefore [straightforwardly supports C++20 module compilation](https://discourse.llvm.org/t/clang-cl-exe-support-for-c-modules/72257/28) equally as well as the latter.https://gitlab.kitware.com/cmake/cmake/-/issues/25730Generated Xcode project can't run command line binary.2024-03-02T16:36:25-05:00Vince HarronGenerated Xcode project can't run command line binary.```
vince@aeris build % sysctl -n machdep.cpu.brand_string
Apple M2 Max
vince@aeris build % sw_vers
ProductName: macOS
ProductVersion: 14.2.1
BuildVersion: 23C71
vince@aeris build % cmake --version
cmake version 3.28.3
```
Xcode Ver...```
vince@aeris build % sysctl -n machdep.cpu.brand_string
Apple M2 Max
vince@aeris build % sw_vers
ProductName: macOS
ProductVersion: 14.2.1
BuildVersion: 23C71
vince@aeris build % cmake --version
cmake version 3.28.3
```
Xcode Version 15.2 (15C500b)
```
vince@aeris cmake_fail % cat CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(my_project)
# GoogleTest requires at least C++14
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
enable_testing()
add_executable(
hello_test
hello_test.cc
)
target_link_libraries(
hello_test
GTest::gtest_main
)
include(GoogleTest)
gtest_discover_tests(hello_test)
vince@aeris cmake_fail % cat hello_test.cc
#include <gtest/gtest.h>
// Demonstrate some basic assertions.
TEST(HelloTest, BasicAssertions) {
// Expect two strings not to be equal.
EXPECT_STRNE("hello", "world");
// Expect equality.
EXPECT_EQ(7 * 6, 42);
}
vince@aeris cmake_fail % mkdir build && cd build && cmake -G Xcode .. && open my_project.xcodeproj
```
Select hello_test scheme, click "Run"
EXPECTED:
Test runs successfully.
ACTUAL:
```
Showing Recent Messages
PhaseScriptExecution CMake\ PostBuild\ Rules /Users/vince/dev/cmake_fail/build/build/hello_test.build/Debug/Script-ABF5F6C0A59A391A2B281592.sh (in target 'hello_test' from project 'my_project')
cd /Users/vince/dev/cmake_fail
/bin/sh -c /Users/vince/dev/cmake_fail/build/build/hello_test.build/Debug/Script-ABF5F6C0A59A391A2B281592.sh
CMake Error at /opt/homebrew/Cellar/cmake/3.28.3/share/cmake/Modules/GoogleTestAddTests.cmake:112 (message):
Error running test executable.
Path: '/Users/vince/dev/cmake_fail/build/Debug/hello_test'
Result: Subprocess killed
Output:
Call Stack (most recent call first):
/opt/homebrew/Cellar/cmake/3.28.3/share/cmake/Modules/GoogleTestAddTests.cmake:225 (gtest_discover_tests_impl)
Command PhaseScriptExecution failed with a nonzero exit code
CMake Error at /opt/homebrew/Cellar/cmake/3.28.3/share/cmake/Modules/GoogleTestAddTests.cmake:112 (message):
Error running test executable.
Path: '/Users/vince/dev/cmake_fail/build/Debug/hello_test'
Result: Subprocess killed
Output:
Call Stack (most recent call first):
/opt/homebrew/Cellar/cmake/3.28.3/share/cmake/Modules/GoogleTestAddTests.cmake:225 (gtest_discover_tests_impl)
Command PhaseScriptExecution failed with a nonzero exit code
```
If I try to run the binary from the command line, I get this:
```
vince@aeris build % Debug/hello_test
zsh: killed Debug/hello_test
```
ADDITIONAL INFORMATION:
If I try using the makefile generator, ctest/hello_test works fine.
```
vince@aeris cmake_fail % rm -rf build
vince@aeris cmake_fail % cmake -S . -B build
-- The C compiler identification is AppleClang 15.0.0.15000100
-- The CXX compiler identification is AppleClang 15.0.0.15000100
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Warning (dev) at /opt/homebrew/Cellar/cmake/3.28.3/share/cmake/Modules/FetchContent.cmake:1331 (message):
The DOWNLOAD_EXTRACT_TIMESTAMP option was not given and policy CMP0135 is
not set. The policy's OLD behavior will be used. When using a URL
download, the timestamps of extracted files should preferably be that of
the time of extraction, otherwise code that depends on the extracted
contents might not be rebuilt if the URL changes. The OLD behavior
preserves the timestamps from the archive instead, but this is usually not
what you want. Update your project to the NEW behavior or specify the
DOWNLOAD_EXTRACT_TIMESTAMP option with a value of true to avoid this
robustness issue.
Call Stack (most recent call first):
CMakeLists.txt:9 (FetchContent_Declare)
This warning is for project developers. Use -Wno-dev to suppress it.
-- Found Python: /opt/homebrew/Frameworks/Python.framework/Versions/3.11/bin/python3.11 (found version "3.11.4") found components: Interpreter
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Configuring done (2.7s)
-- Generating done (0.0s)
-- Build files have been written to: /Users/vince/dev/cmake_fail/build
vince@aeris cmake_fail % cmake --build build
[ 10%] Building CXX object _deps/googletest-build/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o
[ 20%] Linking CXX static library ../../../lib/libgtest.a
[ 20%] Built target gtest
[ 30%] Building CXX object _deps/googletest-build/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o
[ 40%] Linking CXX static library ../../../lib/libgtest_main.a
[ 40%] Built target gtest_main
[ 50%] Building CXX object CMakeFiles/hello_test.dir/hello_test.cc.o
[ 60%] Linking CXX executable hello_test
[ 60%] Built target hello_test
[ 70%] Building CXX object _deps/googletest-build/googlemock/CMakeFiles/gmock.dir/src/gmock-all.cc.o
[ 80%] Linking CXX static library ../../../lib/libgmock.a
[ 80%] Built target gmock
[ 90%] Building CXX object _deps/googletest-build/googlemock/CMakeFiles/gmock_main.dir/src/gmock_main.cc.o
[100%] Linking CXX static library ../../../lib/libgmock_main.a
[100%] Built target gmock_main
vince@aeris cmake_fail % cd build && ctest
Test project /Users/vince/dev/cmake_fail/build
Start 1: HelloTest.BasicAssertions
1/1 Test #1: HelloTest.BasicAssertions ........ Passed 0.01 sec
100% tests passed, 0 tests failed out of 1
Total Test time (real) = 0.01 sec
vince@aeris build % ls
CMakeCache.txt Makefile bin hello_test[1]_include.cmake
CMakeFiles Testing cmake_install.cmake hello_test[1]_tests.cmake
CTestTestfile.cmake _deps hello_test lib
vince@aeris build % ./hello_test
Running main() from /Users/vince/dev/cmake_fail/build/_deps/googletest-src/googletest/src/gtest_main.cc
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from HelloTest
[ RUN ] HelloTest.BasicAssertions
[ OK ] HelloTest.BasicAssertions (0 ms)
[----------] 1 test from HelloTest (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 1 test.
```https://gitlab.kitware.com/cmake/cmake/-/issues/25729Makefile: target with LINK_DEPENDS on custom command output says "no rule to ...2024-03-04T09:50:38-05:00Tal RisinMakefile: target with LINK_DEPENDS on custom command output says "no rule to make target"Tested on CMake 3.22.1 Minimal example:
```
cmake_minimum_required(VERSION 3.22)
project("example" LANGUAGES C)
add_executable(example main.c)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/linkerscript.ld
DEPENDS ${...Tested on CMake 3.22.1 Minimal example:
```
cmake_minimum_required(VERSION 3.22)
project("example" LANGUAGES C)
add_executable(example main.c)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/linkerscript.ld
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/linkerscript.in
COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/linkerscript.in ${CMAKE_CURRENT_BINARY_DIR}/linkerscript.ld
COMMENT Generates linkerscript with custom sections
)
# Notice that LINK_DEPENDS of example is set to the generated linkerscript
set_target_properties(example PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/linkerscript.ld)
target_link_options(example PRIVATE -T${CMAKE_CURRENT_BINARY_DIR}/linkerscript.ld)
```
when building with Makefiles, get the following output:
```log
[ 50%] Building C object CMakeFiles/example.dir/main.c.o
gmake[2]: *** No rule to make target 'linkerscript.ld', needed by 'example'. Stop.
gmake[1]: *** [CMakeFiles/Makefile2:84: CMakeFiles/example.dir/all] Error 2
gmake: *** [Makefile:91: all] Error
```
When building with `-GNinja`, `linkerscript.ld` is generated successfully and used for linking.
`main.c` - doesn't matter, example:
```
#include <stdio.h>
int main() {
printf("Hello world!\n");
}
```
`linkerscript.in` - doesn't matter, can be an empty file.
If I add a custom target and get `example` to depend on it then this works with Makefile as well:
```
add_custom_target(linkerscript DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/linkerscript.ld)
add_dependencies(example linkerscript)
```https://gitlab.kitware.com/cmake/cmake/-/issues/25728GenEx: Duplicate transitive target INTERFACE property in other target context...2024-03-17T10:09:51-04:00Michael Herwigcontact@michael-herwig.deGenEx: Duplicate transitive target INTERFACE property in other target context lead to incorrect results## Description
The evaluation of a generator expression for transitive interface properties `$<TARGET_PROEPRTY:target,INTERFACE_*>` that occurs multiple times in the evaluation of a single generator expression but in the context of a di...## Description
The evaluation of a generator expression for transitive interface properties `$<TARGET_PROEPRTY:target,INTERFACE_*>` that occurs multiple times in the evaluation of a single generator expression but in the context of a different target leads to empty results after its' first evaluation.
## Error Cause
The `cmGeneratorTarget` class has an extra evaluation for interface properties `cmGeneratorTarget::EvaluateInterfaceProperty` which returns an empty string for already encountered references (see `cmGeneratorExpressionDAGChecker::ALREADY_SEEN`). This seems to be a bug.
## Possible Fix (?)
Re-evalute the same generator expression multiple times, or cache the result of previous evaluated expressions. I would not prefer the second options, as this seems to introduce overhead for large expression that do not share common expressions. Either by caching too many unused results or by precomputing shared references of interest.
## Reproduce
To reproduce the inconsistent behavior, I made a small project file that will only succeed in building if the generator expression with and without root target context will result in the same output.
`CMakeLists.txt`
```cmake
cmake_minimum_required(VERSION 3.26)
project(Bug LANGUAGES NONE)
add_library(source INTERFACE)
target_sources(source INTERFACE foo.c bar.cpp)
set(sourceSources $<TARGET_PROPERTY:source,INTERFACE_SOURCES>)
set(cSources $<LIST:FILTER,${sourceSources},INCLUDE,.*\\.c$>)
set(cppSources $<LIST:FILTER,${sourceSources},EXCLUDE,.*\\.c$>)
set(allSources $<LIST:APPEND,${cSources},${cppSources}>)
add_library(sink INTERFACE)
target_sources(sink INTERFACE ${allSources})
set(targetSources $<TARGET_PROPERTY:sink,INTERFACE_SOURCES>)
file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/output_sink.txt CONTENT $<JOIN:${targetSources},\n>)
file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/output_all.txt CONTENT $<JOIN:${allSources},\n>)
set(eqCheck $<STREQUAL:$<JOIN:$<LIST:SORT,${allSources}>,>,$<JOIN:$<LIST:SORT,${targetSources}>,>>)
add_custom_target(check ALL COMMAND ${CMAKE_COMMAND} -E $<IF:${eqCheck},true,false>)
```
### Explanation
The generator expression `LIST:APPEND` creates a DAG with a shared sink `TARGET_PROPERTY:INTERFACE_SOURCES`. One of the intermediate expressions evaluates the C source, and the other returns the CPP source. This expression works as expected unless the generator expression is assessed in the context of another target. In that case, the second evaluation (filtering the CPP file) of `TARGET_PROPERTY:INTERFACE_SOURCES` returns an empty string; thus, only the C file is received.
```mermaid
graph TD;
LIST:APPEND-->FILTER:INCLUDE,.*\\.c$;
LIST:APPEND-->FILTER:EXCLUDE,.*\\.c$;
FILTER:INCLUDE,.*\\.c$ -->TARGET_PROPERTY:INTERFACE_SOURCES;
FILTER:EXCLUDE,.*\\.c$ -->TARGET_PROPERTY:INTERFACE_SOURCES;
```
After configuring the project, the binary directory will contain two files. The first `output_all.txt` contains both source files, and the second `output_sink.txt` contains only the C file.
Here, I used an intermediate target `sink` with `target_sources` as the context to trigger that behavior, but other target contexts also suffice. For example: `add_custom_target(check ALL COMMAND ${CMAKE_COMMAND} -E echo $<JOIN:${allSources},\n>)` will only print the C file.https://gitlab.kitware.com/cmake/cmake/-/issues/25724Fortran: Unrecognized flag '-F' provided to gfortran on macOS when linking to...2024-03-05T08:12:36-05:00Willem DeconinckFortran: Unrecognized flag '-F' provided to gfortran on macOS when linking to a FrameworkArchitecture: macOS 13.5 (Ventura) with gfortran [GNU Fortran (Homebrew GCC 13.2.0) 13.2.0]
Problem description:
--------------------
I am trying to build a Fortran target linking with LAPACK:
```
target_link_libraries(MyFortranTarget P...Architecture: macOS 13.5 (Ventura) with gfortran [GNU Fortran (Homebrew GCC 13.2.0) 13.2.0]
Problem description:
--------------------
I am trying to build a Fortran target linking with LAPACK:
```
target_link_libraries(MyFortranTarget PRIVATE ${LAPACK_LIBRARIES})
```
The variable `LAPACK_LIBRARIES` is set via `find_package(LAPACK)` and reads:
```
/Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk/System/Library/Frameworks/Accelerate.framework -lm -ldl
```
Since MR https://gitlab.kitware.com/cmake/cmake/-/merge_requests/7121 this now adds following flag to the compilation of each Fortran file:
```
-F/Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk/System/Library/Frameworks
```
This flag is not supported with gfortran resulting in a warning emitted for each compiled file:
```
f951: Warning: command-line option '-F/Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk/System/Library/Frameworks' is valid for C/C++/ObjC/ObjC++ but not for Fortran
```
I think it is very unlikely that Fortran source code could make use of any header includes from any available Framework.https://gitlab.kitware.com/cmake/cmake/-/issues/25723cmake_host_system_information: Wrong number of core on ARM64 system2024-03-04T03:33:45-05:00Thomas GUIGNONcmake_host_system_information: Wrong number of core on ARM64 systemHello,
On our 80 cores ARM system (CentOS Linux release 7.9.2009 (AltArch)) the function
```cmake
cmake_host_system_information(RESULT NCORE QUERY NUMBER_OF_PHYSICAL_CORES)
```
gives 1 core
we use cmake 3.28.1 (also observed with cma...Hello,
On our 80 cores ARM system (CentOS Linux release 7.9.2009 (AltArch)) the function
```cmake
cmake_host_system_information(RESULT NCORE QUERY NUMBER_OF_PHYSICAL_CORES)
```
gives 1 core
we use cmake 3.28.1 (also observed with cmake 3.22.1)https://gitlab.kitware.com/cmake/cmake/-/issues/25722FindVulkan: Not accounting for new dxc / volk debug binaries2024-02-27T17:54:04-05:00Juan RamosFindVulkan: Not accounting for new dxc / volk debug binariesAs of Vulkan SDK `1.3.268` `Debug` versions of the DXC and VOLK libraries have been included in the SDK (dxcompilerd.dll, dxcompilerd.lib, volkd.lib).
See the release notes here:
https://vulkan.lunarg.com/doc/sdk/1.3.268.0/windows/relea...As of Vulkan SDK `1.3.268` `Debug` versions of the DXC and VOLK libraries have been included in the SDK (dxcompilerd.dll, dxcompilerd.lib, volkd.lib).
See the release notes here:
https://vulkan.lunarg.com/doc/sdk/1.3.268.0/windows/release_notes.html
This will require fixes to `FindVulkan.cmake` to properly account for the new binaries.
Originally reported on discourse:
https://discourse.cmake.org/t/findvulkan-cmake-cant-find-dxc-debug-libraries-while-present-as-its-not-looking-for-them/10198https://gitlab.kitware.com/cmake/cmake/-/issues/25719CMAKE_XCODE_GENERATE_SCHEME should default to YES2024-03-12T11:52:19-04:00Dave AbrahamsCMAKE_XCODE_GENERATE_SCHEME should default to YESOr so I assert. A fully-functional Xcode project is more useful than one with no schemes and turning it on by default would prevent people from filing issues because they haven't discovered it.Or so I assert. A fully-functional Xcode project is more useful than one with no schemes and turning it on by default would prevent people from filing issues because they haven't discovered it.https://gitlab.kitware.com/cmake/cmake/-/issues/25718Dependency provider support for ExternalProject?2024-02-29T00:06:06-05:00Linus HeckemannDependency provider support for ExternalProject?Dependency providers are awesome and the feature has been really helpful for taking control over dependencies brought in using FetchContent by projects that I'm building to replace them with local development checkouts.
It would be real...Dependency providers are awesome and the feature has been really helpful for taking control over dependencies brought in using FetchContent by projects that I'm building to replace them with local development checkouts.
It would be really nice if it were possible to apply the same technique to ExternalProject as well.
I'll admit though that I don't have a deep understanding of the differences between ExternalProject and FetchContent (besides configure/build-time fetching) and whether the concept is applicable in the same way. Would this make sense?https://gitlab.kitware.com/cmake/cmake/-/issues/25717Feature Request: Latest Language Standard Specification2024-03-05T20:55:41-05:00Tyler NicholsFeature Request: Latest Language Standard Specification## Summary
The MSVC has a means to specify that the latest C++ standard should be used via the `/std:c++latest` command line argument. It would be convenient if CMake provided a similar facility when generating build files so that users ...## Summary
The MSVC has a means to specify that the latest C++ standard should be used via the `/std:c++latest` command line argument. It would be convenient if CMake provided a similar facility when generating build files so that users did not have to update their own CMake scripts to account for a new version of the language standard for their project.
_(NOTE: Throughout this issue, I will be referring to the C++ standard in particular. However, this feature can and should be applied to all languages whose standards are recognized by CMake - namely, C, C++, CUDA/C++, and HIP.)_
## Use Cases
For many larger projects with a substantial list of dependencies and supported platforms, it can make sense to specify a hard limit on the language standard (e.g., C++17). However, for smaller projects or those which are built in a more controlled environment, being able to easily specify that the latest C++ standard be used can be convenient.
Anecdotally, I have written and used a CMake function similar to the following for defining the C++ language standard used in my own personal projects:
```cmake
function(GetLatestCXXStandard OUT_CXX_STANDARD)
set(${OUT_CXX_STANDARD} cxx_std_23 PARENT_SCOPE)
endfunction()
# ...
add_library(SomeLibrary)
GetLatestCXXStandard(LATEST_CXX_STANDARD)
target_compile_features(SomeLibrary
PRIVATE
${LATEST_CXX_STANDARD}
)
```
This works, but it requires that the user manually update the implementation of the `GetLatestCXXStandard()` function to account for an update in build environment or language standard (even if it only happens every, say, three years). It would be more convenient and future proof if CMake offered a standardized method for specifying that the latest supported C++ standard be used to compile a given target.
## Feature Details
The proposed approach is for CMake to expose a `CMAKE_CXX_STANDARD_LATEST` variable which is assigned an integer value representing the latest C++ standard supported by the current compiler (e.g., `23` for C++23). This can then be used to specify the C++ standard level for a target:
```cmake
# Set the latest C++ standard as the default for created targets.
set(CMAKE_CXX_STANDARD ${CMAKE_CXX_STANDARD_LATEST})
# === OR ===
# Set the latest C++ standard for a specific target.
target_compile_features(SomeLibrary PRIVATE cxx_std_${CMAKE_CXX_STANDARD_LATEST})
```
It would also be possible for script developers to use the value of this variable to conditionally enable optional features for a distributed library. However, we should stress in the documentation that integer comparisons will **not** work between C++ standard versions. This is because some older standards have a greater numerical value than newer standards. The documentation can include a code sample like the following to demonstrate how one could correctly perform this check:
```cmake
# Careful! We cannot do direct integer comparisons with CMAKE_CXX_STANDARD_LATEST
# because some earlier C++ standards (e.g., C++98) will have a higher numerical
# value than our requirement (C++17).
#
# Instead, we keep a list of unsupported C++ standards and check if
# CMAKE_CXX_STANDARD_LATEST appears in that list.
set(UNSUPPORTED_CXX_STANDARDS
98
11
14
)
list(FIND UNSUPPORTED_CXX_STANDARDS ${CMAKE_CXX_STANDARD_LATEST} UNSUPPORTED_CXX_STANDARDS_INDEX)
if(UNSUPPORTED_CXX_STANDARDS_INDEX EQUAL -1)
# Enabling some optional feature...
else()
message(STATUS
"Feature X is disabled because it requires C++17, but the current compiler "
"only supports C++${CMAKE_CXX_STANDARD_LATEST}."
)
endif()
```
#### Other Approaches
This section contains ideas which were at one point proposed, but have since been rejected for implementation. They are kept here for reference.
<details><summary>cxx_std_latest Compile Feature</summary>
One approach would be to add a new `cxx_std_latest` (or similarly named) compile feature to the `CMAKE_CXX_KNOWN_FEATURES` list. Then, users would be able to write CMake code like the following to automatically build their project with the latest supported standard:
```cmake
add_library(SomeLibrary)
target_compile_features(SomeLibrary
PRIVATE
cxx_std_latest
)
```
This behavior has actually been implemented in [this branch](https://gitlab.kitware.com/tylerbrawl/cmake/-/tree/tnichols/features/cxx_std_latest), and !9288 was submitted as a merge request. However, that request was closed for further discussion. Furthermore, @brad.king pointed out in [this comment](https://gitlab.kitware.com/cmake/cmake/-/issues/25717#note_1486874) that this proposal is fundamentally flawed as a compile feature. Essentially, `cxx_std_latest` cannot safely be in the `INTERFACE_COMPILE_FEATURES` list of a distributed project because it would imply different requirements in different build environments.
</details>https://gitlab.kitware.com/cmake/cmake/-/issues/25716string(JSON SET) fails to handle strings that start with the `true` or `false...2024-02-26T16:00:36-05:00Robert Maynardstring(JSON SET) fails to handle strings that start with the `true` or `false` substring
Consider the following CMake example:
```
function(add_element json_blob_var key value)
string(JSON result ERROR_VARIABLE error SET "${${json_blob_var}}" ${key} ${value})
if(error)
string(JSON result ERROR_VARIABLE error SET "${...
Consider the following CMake example:
```
function(add_element json_blob_var key value)
string(JSON result ERROR_VARIABLE error SET "${${json_blob_var}}" ${key} ${value})
if(error)
string(JSON result ERROR_VARIABLE error SET "${${json_blob_var}}" ${key} "\"${value}\"")
endif()
set(${json_blob_var} "${result}" PARENT_SCOPE)
endfunction()
set(json [=[{ }]=])
add_element(json a 1)
add_element(json b false)
add_element(json c "[1,2,3]")
add_element(json e "string false")
add_element(json f string_false)
add_element(json g "false_string")
message(STATUS "result: ${json}")
```
This function attempts to add each item as the literal type to handle `booleans`, `objects, etc. If that fails it adds them as string types.
In this case we see `false_string` being incorrectly treated as the boolean `false`
Output:
```
-- result: {
"a" : 1,
"b" : false,
"c" : [ 1, 2, 3 ],
"e" : "string false",
"f" : "string_false",
"g" : false
}
```https://gitlab.kitware.com/cmake/cmake/-/issues/25714<projectName>_SOURCE_DIR and <projectName>_BINARY_DIR can be masked by non-ca...2024-03-06T09:42:16-05:00Craig Scott<projectName>_SOURCE_DIR and <projectName>_BINARY_DIR can be masked by non-cache variablesConsider the following minimal project (not something you'd do directly, it's just a minimal reproducer):
```cmake
cmake_minimum_required(VERSION 3.21) # CMP0126 set to NEW
set(something_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) # S...Consider the following minimal project (not something you'd do directly, it's just a minimal reproducer):
```cmake
cmake_minimum_required(VERSION 3.21) # CMP0126 set to NEW
set(something_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) # Something different just so we can see the result
project(something LANGUAGES NONE)
message(STATUS "something_SOURCE_DIR = ${something_SOURCE_DIR}")
```
The `project()` command is documented as setting `<projectName>_SOURCE_DIR` and `<projectName>_BINARY_DIR`, but as the above snippet demonstrates, it doesn't quite work in all situations. What the `project()` command actually does is set _cache_ variables, but with CMP0126 set to NEW, if these variables already exist as non-cache variables in the calling scope, those non-cache variables will be hidden.
An important scenario where this crops up can be seen with GoogleTest. That project has a directory structure like so:
```
ROOT
+-- CMakeLists.txt
| ... project(googletest-distribution)
|
+-- googletest
| +-- CMakeLists.txt
| ... project(gtest)
+-- googlemock
+-- CMakeLists.txt
... project(gmock)
```
Other projects often pull in GoogleTest using FetchContent like so:
```cmake
include(FetchContent)
FetchContent_Declare(
gtest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.14.0
)
FetchContent_MakeAvailable(gtest)
```
One of the effects of calling `FetchContent_MakeAvailable(<depName>)` is that it will set non-cache variables named `<lowercaseDepName>_SOURCE_DIR` and `<lowercaseDepName>_BINARY_DIR`, and it will set those variables _before_ populating the dependency. The `<lowercaseDepName>_SOURCE_DIR` variable will point at the ROOT directory of GoogleTest, but note how the `googletest` subdirectory below the ROOT has a call to `project(gtest)`. Now we have two conflicting values for `gtest_SOURCE_DIR`. Within GoogleTest's own source tree, the `project(gtest)` call wants `gtest_SOURCE_DIR` to point to the `googletest` subdirectory below the ROOT, but `FetchContent_MakeAvailable()` will set `gtest_SOURCE_DIR` to point to the ROOT itself. This non-cache `gtest_SOURCE_DIR` variable will exist when the GoogleTest sources are read and processed, which means the `gtest_SOURCE_DIR` cache variable created by the call to `project(gtest)` will never be seen outside of the directory scope where `project(gtest)` is called. As it happens, the `googlemock/CMakeLists.txt` file tries to do exactly that, so it ends up seeing a different value for `gtest_SOURCE_DIR` than what it expected. I suspect this is related to the problem reported in #25294.
One idea would be to change `project()` to set non-cache variables for `<projectName>_SOURCE_DIR` and `<projectName>_BINARY_DIR` instead of cache variables. This would mean code outside of the project's directory scope would no longer see these variables, so a policy would be needed. But a policy would only apply to where `project()` is called, not to code outside of that directory scope where the cache variables may be expected. Such a change would also leave code outside the project's directory scope with no easy way to obtain the project's source or build directory. The GoogleTest example demonstrates this may be a problem.
At the very least, we should update the documentation for `project()` and `FetchContent` to highlight the unreliability of using `<projectName>_SOURCE_DIR` and `<projectName>_BINARY_DIR` variables, and the relevance of policy CMP0126 to the situation.https://gitlab.kitware.com/cmake/cmake/-/issues/25709Confusing error message and inappropriate followup action when CUDA compiler ...2024-02-22T17:30:02-05:00Eyal Rozenbergeyalroz1@gmx.comConfusing error message and inappropriate followup action when CUDA compiler is missingUsing CMake 3.29.0-rc1.
With the following list file:
```
cmake_minimum_required(VERSION 3.25)
project(foo CUDA)
```
and invoking:
```
$ cmake -B build -DCMAKE_CUDA_COMPILER=/usr/local/cuda-12.34.no-such-version/bin/nvcc
```
I see this:...Using CMake 3.29.0-rc1.
With the following list file:
```
cmake_minimum_required(VERSION 3.25)
project(foo CUDA)
```
and invoking:
```
$ cmake -B build -DCMAKE_CUDA_COMPILER=/usr/local/cuda-12.34.no-such-version/bin/nvcc
```
I see this:
```
-- The CUDA compiler identification is unknown
CMake Error at /opt/versions/cmake/3.29.0-rc1/share/cmake-3.29/Modules/CMakeDetermineCUDACompiler.cmake:266 (message):
Failed to detect a default CUDA architecture.
Compiler output:
Call Stack (most recent call first):
CMakeLists.txt:2 (project)
```
This is a poor combination of error messages:
* The first line suggest a CUDA compiler does exist, but is just of "unknown identification" - which is not the case, it's simply not at the specified path.
* The second warning suggests some kind of procedure was undertaken to detect the default CUDA architecture, but actually, it wasn't, since that procedure requires a CUDA compiler, which isn't there
instead, I expect to be told that the CUDA compiler was not found; and then, I expect CMake not try to detect the CUDA architecture, given that CMake knows that the detection requires the CUDA compiler.https://gitlab.kitware.com/cmake/cmake/-/issues/25706Removing `-O` flag in specific target2024-02-24T00:05:11-05:00Cristian LeRemoving `-O` flag in specific targetWe are encountering an issue that a project is failing to build with `-Ox` and has to be built with `-O0`. This is fine because it is non-critical and used for a test-suite.
**Question**: How can we remove the default compile flags from...We are encountering an issue that a project is failing to build with `-Ox` and has to be built with `-O0`. This is fine because it is non-critical and used for a test-suite.
**Question**: How can we remove the default compile flags from `CMAKE_<LANG>_COMPILE_FLAGS_<CONFIG>`? We want to support `FetchContent` so the config could be arbitrary.
@craig.scott suggested [^1] we should edit `COMPILE_OPTIONS`/`COMPILE_FLAGS` directory/target property, but we have tried to print those for CMake 3.22 but it was empty. Any suggestions on what is wrong there? My assumption was that the genex is not displayed, but we tried to overwrite it, but it did not have any effect.
[^1]: https://discourse.cmake.org/t/how-do-i-replace-the-compiler-options-for-one-target/7815/4https://gitlab.kitware.com/cmake/cmake/-/issues/25705ci: Add sonarcloud annotation links2024-02-21T21:58:26-05:00Ben Boeckelci: Add sonarcloud annotation linksThe following discussion from !9267 should be addressed:
- [ ] @ben.boeckel started a [discussion](https://gitlab.kitware.com/cmake/cmake/-/merge_requests/9267#note_1484439): (+2 comments)
> Do we know the URL where results will b...The following discussion from !9267 should be addressed:
- [ ] @ben.boeckel started a [discussion](https://gitlab.kitware.com/cmake/cmake/-/merge_requests/9267#note_1484439): (+2 comments)
> Do we know the URL where results will be available based on the commit metadata (e.g., the commit hash)? If we do, the robot could craft a URL to add to pipelines with the job (I think there are some missing connections to actually do it, but it could serve as incentive to complete them).
We can craft the link based on the reason the pipeline is running.
Cc: @ryan.krattiger1https://gitlab.kitware.com/cmake/cmake/-/issues/25703Documentation doesn't fully explain ENVIRONMENT_MODIFICATION2024-02-22T08:13:48-05:00Dave AbrahamsDocumentation doesn't fully explain ENVIRONMENT_MODIFICATIONAt least not in the `--help` docs. @ben.boeckel [encouraged me](https://discourse.cmake.org/t/variables-for-cross-platform-code/10115/8?u=dabrahams) to file this bug.At least not in the `--help` docs. @ben.boeckel [encouraged me](https://discourse.cmake.org/t/variables-for-cross-platform-code/10115/8?u=dabrahams) to file this bug.https://gitlab.kitware.com/cmake/cmake/-/issues/25701curl: May use weak encryption algorithms2024-03-13T11:05:21-04:00William Sciaronicurl: May use weak encryption algorithms# Background
Static Analysis revealed the following uses of `curl_easy_init` not followed by any `CURLOPT_SSLVERSION` setting:
- [`Source/CTest/cmCTestSubmitHandler.cxx`](https://gitlab.kitware.com/cmake/cmake/-/blob/v3.28.3/Source/CTe...# Background
Static Analysis revealed the following uses of `curl_easy_init` not followed by any `CURLOPT_SSLVERSION` setting:
- [`Source/CTest/cmCTestSubmitHandler.cxx`](https://gitlab.kitware.com/cmake/cmake/-/blob/v3.28.3/Source/CTest/cmCTestSubmitHandler.cxx#L176)
- [`Source/cmFileCommand.cxx`](https://gitlab.kitware.com/cmake/cmake/-/blob/v3.28.3/Source/cmFileCommand.cxx#L2032)
- [`Utilities/cmcurl/curltest.c`](https://gitlab.kitware.com/cmake/cmake/-/blob/v3.28.3/Utilities/cmcurl/curltest.c#L36)
- [`Utilities/cmcurl/lib/conncache.c`](https://gitlab.kitware.com/cmake/cmake/-/blob/v3.28.3/Utilities/cmcurl/lib/conncache.c#L107)
# Possible Solution
Add `curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);` to explicitly set the SSL TLS version.
It may be desirable to give the user the option to use deprecated encryption algorithms by wrapping this in an option that defaults to `ON`.3.30.0Brad KingBrad Kinghttps://gitlab.kitware.com/cmake/cmake/-/issues/25700VS: --resolve-package-references=only starts building if the project has no p...2024-02-21T13:47:49-05:00Balázs OrosziVS: --resolve-package-references=only starts building if the project has no packages to restoreIf you execute `cmake --build <build_dir> --resolve-package-references=only` on a build dir of a project that has no package references, then cmake starts building, which is unexpected.
It seems this may be due to the following conditi...If you execute `cmake --build <build_dir> --resolve-package-references=only` on a build dir of a project that has no package references, then cmake starts building, which is unexpected.
It seems this may be due to the following condition in cmGlobalVisualStudio10Generator.cxx:
```
...
// If a restore is required, evaluate the restore mode.
if (requiresRestore) {
if (restoreMode == PackageResolveMode::OnlyResolve) {
// Only invoke the restore target on the project.
makeCommand.Add("/t:Restore");
} else {
...
```
I would expect the above command to do nothing if there are no packages to restore (but certainly not to start building).https://gitlab.kitware.com/cmake/cmake/-/issues/25697Make checking for $<TARGET_OBJECTS:...> in Xcode generator expressions less s...2024-02-21T11:47:13-05:00Yauheni KhnykinMake checking for $<TARGET_OBJECTS:...> in Xcode generator expressions less strict.Hi,
Consider have the following script:
```
add_library(FooObj OBJECT foo.cpp)
add_library(FooIntf INTERFACE)
target_sources(FooIntf INTERFACE $<TARGET_OBJECTS:FooObj>)
target_link_libraries(FooIntf INTERFACE FooObj)
add_library(FooS...Hi,
Consider have the following script:
```
add_library(FooObj OBJECT foo.cpp)
add_library(FooIntf INTERFACE)
target_sources(FooIntf INTERFACE $<TARGET_OBJECTS:FooObj>)
target_link_libraries(FooIntf INTERFACE FooObj)
add_library(FooShared SHARED foo.cpp)
target_link_libraries(FooShared PUBLIC FooIntf)
file(GENERATE OUTPUT "test.txt"
CONTENT "$<FILTER:$<TARGET_PROPERTY:FooShared,SOURCES>,INCLUDE,.*\\.cpp$>")
```
When I try to configure this for Xcode for simulator with several architectures I get:
```
> cmake .. -GXcode -DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_SYSTEM_NAME=iOS
...
CMake Error at CMakeLists.txt:10 (target_link_libraries):
...
Error evaluating generator expression:
$<TARGET_OBJECTS:FooObj>
The evaluation of the TARGET_OBJECTS generator expression is only suitable
for consumption by CMake (limited under Xcode with multiple architectures).
It is not suitable for writing out elsewhere.
```
I understand the reason why this check is added, but in my particular example it doesn't make sense because it can be filtered out.
The questions are:
- Is it possible to avoid this issue with some generator expression?
- If not, can this check be moved to later stage when `FILTER` is already processed elements?https://gitlab.kitware.com/cmake/cmake/-/issues/25695Documentation / default generator2024-02-21T08:07:22-05:00Robert HueDocumentation / default generatorWhen I run from the command line the command `cmake -G`, I get the list of all the available generators.
A star may be in front of one of them. I suppose it is the generator set in CMAKE_GENERATOR environment variable.
But this star is...When I run from the command line the command `cmake -G`, I get the list of all the available generators.
A star may be in front of one of them. I suppose it is the generator set in CMAKE_GENERATOR environment variable.
But this star isn't mentionned in the documentation of the cmake command :
https://cmake.org/cmake/help/latest/manual/cmake.1.html#cmdoption-cmake-G