I'd like to use C++20 in MSVC but I can't use the new char8_t in my project. MSVC provides a flag to disable char8_t: /Zc:char8_t-. This works fine if I use a MSVC solution project but it is ignored somehow in my CMAKE project and the compilation fails.
My CMakeLists.txt:
cmake_minimum_required (VERSION 3.12)
project ("CmakeTest")
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:char8_t-")
add_executable (CmakeTest "CmakeTest.cpp" )
CMakeTest.cpp
#include <filesystem>
int main()
{
std::filesystem::path path;
std::string test = path.u8string();
return 0;
}
Until C++17 u8string() returned a std::string, so this compiled fine. But since C++ 20 it returns a std::u8string and the compilation fails. The flag "/Zc:char8_t-" should return to the old functionality, but the compilation still fails with the same error that there is no conversion possible from std::u8string to std::string.
The resulting call to cl.exe looks fine and includes the flag:
C:\PROGRA~1\MIB055~1\2022\COMMUN~1\VC\Tools\MSVC\1434~1.319\bin\Hostx64\x64\cl.exe /nologo /TP /DWIN32 /D_WINDOWS /W3 /GR /EHsc /Zc:char8_t- /MDd /Zi /Ob0 /Od /RTC1 -std:c++20 /showIncludes /FoCMakeFiles\CmakeTest.dir\CmakeTest.cpp.obj /FdCMakeFiles\CmakeTest.dir\ /FS -c D:\Projects\cmaketest\CmakeTest.cpp
Executing it manually leads to the same error.
Instead of using CMAKE_CXX_STANDARD I am specifying "-std:c++20" manually. I think this is more of workaround but it works.
CMakeLists.txt
cmake_minimum_required (VERSION 3.12)
project ("CmakeTest")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std:c++20 /Zc:char8_t-")
add_executable (CmakeTest "CmakeTest.cpp" )
Related
Note: I've only tested this problem on windows but that's what I want to solve right now.
I'm trying to create a static library and I'm using CMake to generate the build files. However, building leads to no standard libraries being found. The simplest form I reproduce this issue is with these 3 files:
Test.hpp
#pragma once
class A
{
public:
int DoSomething();
};
Test.cpp
#include "Test.hpp"
#include <assert.h>
int A::DoSomething()
{
assert(true);
return 5;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.10.2)
project(MyLib VERSION 1.0.0 DESCRIPTION "My Lib")
set(SOURCE "src/Test.cpp")
if(WIN32)
set(CMAKE_CXX_FLAGS "/std:c++17 /EHsc")
else()
...
endif()
include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
add_library(MyLib STATIC ${SOURCE})
Running cmake is fine but then running cmake --build . I get the following output:
C:\PROGRA~2\MICROS~2\2019\COMMUN~1\VC\Tools\MSVC\1425~1.286\bin\HostX64\x64\cl.exe /nologo /TP -I..\..\..\include /std:c++17 /EHsc /MDd /Zi /Ob0 /Od /RTC1 /showIncludes /FoCMakeFiles\MyLib.dir\src\Test.cpp.obj /FdCMakeFiles\MyLib.dir\MyLib.pdb /FS -c ..\..\..\src\Test.cpp ..\..\..\src\Test.cpp(3): fatal error C1083: Cannot open include file: 'assert.h': No such file or directory
I'm not sure why it can't find assert.h. I'm only using this as an example but this happens with all STL headers. I've also tried using /MD /MT /MTd but it doesn't change anything. Feels like I need to do something special because it's a STATIC library but I couldn't identify what looking around.
We have a CMakeList.txt prepared to work with IDE's like QT Creator, so some team members are using two different solutions, one for Release and a different one for Debug, respectively.
I would like to use Visual Studio 2015, so I need to create one single solution considering both configurations (Release & Debug). How can I set the different configuration flags properly?
Now, CMakeList file looks like this:
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
message("Debug Build")
set(CMAKE_CXX_FLAGS "/DWIN32 /D_WINDOWS /W3 /wd4996 /wd4251 /wd4275 /wd4267 /GR /EHsc /MP")
else()
message("Release Build")
set(CMAKE_CXX_FLAGS "/DWIN32 /D_WINDOWS /WX /W3 /wd4996 /wd4251 /wd4275 /wd4267 /GR /EHsc /MP /Ox")
endif()
So I just can create one single solution adding -D CMAKE_BUILD_TYPE = Release or Debug.
I would like to generate a single solution and then, from VS decide to compile as Debug or Release.
Visual Studio is a multi-configuration generator, so you can easily switch between Release and Debug. No need to use a CUSTOM_BUILD_TYPE argument. In addition, CMake provides generator expressions (e.g. $<$<CONFIG:Debug>: ... >) for setting configuration-specific options such as those in your example. The flags look very similar between Release and Debug, so you can use a generator expression to simply add the extra Release flags.
Also, manually manipulating the CMAKE_CXX_FLAGS variable is discouraged. It is much safer and cleaner to set these flags using target_compile_options():
target_compile_options(YourTarget PRIVATE
/DWIN32 /D_WINDOWS W3 /wd4996 /wd4251 /wd4275 /wd4267 /GR /EHsc /MP
$<$<CONFIG:Release>:/WX;/Ox>
)
I have a project where I need some dependencies and and I use vcpkg to manage them. Now I want to set compile options with add_compile_options( /W4 /WX /std:c++17 ) for my executable and subdirectories but I don't want them to be applied on packages which were loaded with find_package.
This is the code inside my CMakeLists.txt from my test repository:
cmake_minimum_required(VERSION 3.15)
project(test)
set(VCPKG_DEPENDENCIES glm)
# set the build triplet for windows because default is x86-windows
if(WIN32)
set(VCPKG_TARGET_TRIPLET "x64-windows")
add_compile_options( /W4 /WX /std:c++17 )
endif()
get_filename_component(ABS_PATH_VCPKG "./vcpkg" REALPATH)
set(VCPKG_ROOT ${ABS_PATH_VCPKG})
set(CMAKE_TOOLCHAIN_FILE "${ABS_PATH_VCPKG}/scripts/buildsystems/vcpkg.cmake")
# additional folder where find_XXXX functions are searching for packages
set(CMAKE_PREFIX_PATH "${VCPKG_ROOT}/installed/${VCPKG_TARGET_TRIPLET}/share")
foreach(DEPENDENCY ${VCPKG_DEPENDENCIES})
message(STATUS "installing vcpkg dependency: <${DEPENDENCY}>")
execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/vcpkg.exe install ${DEPENDENCY}:${VCPKG_TARGET_TRIPLET} OUTPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg_install_log.txt)
endforeach()
add_executable(test main.cpp)
find_package(glm CONFIG REQUIRED)
target_link_libraries(test PRIVATE glm)
Ans this is my main:
#include <iostream>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
int main()
{
glm::vec3 vec(1.0);
std::cout << ("Hello World!");
return 0;
}
The glm package however is calling add_library with the IMPORTED key which should inform about that this package is a system package and should not get the options applied to.
This is the error code:
[build] Starting build
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --build <path>/cpp_test_Isystem/build --config Debug --target all -- -j 18
[build] [1/2 50% :: 0.752] Building CXX object CMakeFiles\test.dir\main.cpp.obj
[build] FAILED: CMakeFiles/test.dir/main.cpp.obj
[build] <path>\VC\Tools\MSVC\1423~1.281\bin\Hostx64\x64\cl.exe /nologo /TP -I..\vcpkg\installed\x64-windows\include /DWIN32 /D_WINDOWS /GR /EHsc /Zi /Ob0 /Od /RTC1 -MDd /W4 /WX /std:c++17 /showIncludes /FoCMakeFiles\test.dir\main.cpp.obj /FdCMakeFiles\test.dir\ /FS -c ..\main.cpp
[build] <path>\cpp_test_Isystem\vcpkg\installed\x64-windows\include\glm\ext\../detail/type_quat.hpp(58): error C2220: the following warning is treated as an error
[build] <path>\cpp_test_Isystem\vcpkg\installed\x64-windows\include\glm\ext\../detail/type_quat.hpp(137): note: see reference to class template instantiation 'glm::qua<T,Q>' being compiled
[build] <path>\cpp_test_Isystem\vcpkg\installed\x64-windows\include\glm\ext\../detail/type_quat.hpp(58): warning C4201: nonstandard extension used: nameless struct/union
[build] ninja: build stopped: subcommand failed.
[build] Build finished with exit code 1
Your main.cpp file includes this header, so any options that apply to it also apply to the header.
Your options:
Disable the C4201 warning with a #pragma around the #include of GLM headers:
#pragma warning( push )
#pragma warning( disable : 4201 )
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#pragma warning( pop )
Disable the warning from CMake:
target_add_compile_options(test /wd4201)
EDIT: Use a GLM-specific define to silence these warnings (source):
#define GLM_FORCE_SILENT_WARNINGS
(or equivalent with target_add_definitions)
I've a mysterious problem with the "NMake Makefiles" generator.
When I used my CMakeLists for generate a Solution Visual and I build after, he puts all my .obj in the same folder "sql_lite.dir/Debug/". The build success.
But when I use the Nmake generator, he put my .obj in 2 diferent folder :
sql_sqlite.dir/C_/Users/mea/Documents/repos/corealpi/external/sqlite
and
sql_sqlite.dir/C_/Users/mea/Documents/repos/corealpi/external/sqlite/sqlite3.c.obj
I thought the fact I have file.cpp and file.c is the problem of my issue, because I have the following output :
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Configuring done
CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
Missing variable is:
CMAKE_C_COMPILE_OBJECT
And this at the end of Nmake :
[100%] Building C object CMakeFiles/sql_sqlite.dir/C_/Users/mea/Documents/repos/
corealpi/external/sqlite/sqlite3.c.obj
Linking CXX shared library C:\Users\mea\Documents\repos\corealpi\build\cmake_x86
d\bin\sql_sqlite.dll
LINK : fatal error LNK1104: cannot open file 'CMakeFiles/sql_sqlite.dir/C_/Users
/mea/Documents/repos/corealpi/external/sqlite/sqlite3.c.obj'
LINK failed. with 1104
It seems, he not build in the same directory and not build the .obj for the C file's.
Here is my CMakeLists.txt (who's running well under Visual Studio) :
############################### SQLITE ###############################
project(sql_sqlite CXX)
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /MANIFEST:NO")
# Path of Release
SET(BIN_RELEASE_PATH "../../build/cmake_x86")
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${BIN_RELEASE_PATH}/bin/" )
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BIN_RELEASE_PATH}/bin/" )
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${BIN_RELEASE_PATH}/bin/" )
# Path of Debug
SET(BIN_DEBUG_PATH "../../build/cmake_x86d")
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${BIN_DEBUG_PATH}/bin/" )
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BIN_DEBUG_PATH}/bin/" )
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${BIN_DEBUG_PATH}/bin/" )
# Flags
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /Ycstdafx.h /Yustdafx.h /D_USRDLL /DSQL_SQLITE_EXPORTS /D_UNICODE /DUNICODE")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi /GL /Oi /Gy /O2 /GR- /Gm- /OPT /Fosql_sqlite.dir/src/sql_sqlite")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /WX- /ZI /Oy- /Gm /EHsc /MDd /GS /Gd")
set_source_files_properties(../datasec/src/sql_sqlite/stdafx.cpp PROPERTIES COMPILE_FLAGS "/Ycstdafx.h")
set_source_files_properties(../datasec/src/sql_sqlite/main.cpp PROPERTIES COMPILE_FLAGS "/Yustdafx.h")
set_source_files_properties(../external/sqlite/sqlite3.c PROPERTIES COMPILE_FLAGS "/Y-")
# Files of library
add_library(
sql_sqlite
SHARED
../datasec/src/sql_sqlite/stdafx.h
../external/sqlite/sqlite3.h
../datasec/src/sql_sqlite/sql_sqlite.cpp
../datasec/src/sql_sqlite/stdafx.cpp
../datasec/src/sql_sqlite/main.cpp
../external/sqlite/sqlite3.c
)
target_link_libraries(sql_sqlite datasec core)
Please I need help because, I've search on many website, try different solution during many days but anyway, it stand failing linking.
I've trying to put something like that : /Fosql_sqlite.dir/src/sql_sqlite but nothing change.
Do I have to make a special rule for sqlite3.c ? Or have I make something wrong on my CMakeLists.txt ?
Why CMake tells me : Missing variable is: CMAKE_C_COMPILE_OBJECT ?
Thanks for help.
Your PROJECT lines specifes C++ only via the CXX. Maybe removing the CXX will fix the problem so that both C and C++ compilers will be setup. The documentation is here, http://www.cmake.org/cmake/help/v3.2/command/project.html
I've a CMake Project. Now I need to use libcpuid and procps which is automake.
I want to ship so files with executable.
One way is to create a CMakeLists.txt file for libcpuid and procps
Here is an example for a CMakeLists.txt file for lipcpuid:
cmake_minimum_required(VERSION 2.8.12)
project(libcpuid-0.1.0)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# Compiler settings
if (WIN32)
# Standard: /DWIN32 /D_WINDOWS /W3 /Zm1000 /EHsc /GR
set(CMAKE_CXX_FLAGS "/DWIN32 /D_WINDOWS /W4 /Zi /EHsc /GR- /MP /openmp")
endif (WIN32)
file(GLOB libcpuid_SRC *.c *.h)
add_definitions(-DVERSION="0.1.0")
# Create a target for the library
add_library(libcpuid-0.1.0
${libcpuid_SRC}
)
Afterwards in your CMake project you can easily reference to the lib via:
ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/external/libcpuid_0.1.0)
target_link_libraries( YourProject
libcpuid-0.1.0
)