I want to build libpng using CMake, but I cannot build because an error that Policy CMP0074 is not set: find_package uses _ROOT variables has occurred when I configure CMake.
Download zlib-1.2.11 and libpng-1.6.37.
I have written CMakeLists.txt.
add_subdirectory(libpng)
add_subdirectory(zlib)
Libpng in CMakeLists.txt which depends on zlib is as follows:
option(PNG_BUILD_ZLIB "Custom zlib Location, else find_package is used" OFF)
if(NOT PNG_BUILD_ZLIB)
find_package(ZLIB REQUIRED)
include_directories(${ZLIB_INCLUDE_DIR})
endif()
Therefore I set ZLIB_ROOT variable to work find_package command.
set(ZLIB_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/zlib)
add_subdirectory(libpng)
add_subdirectory(zlib)
ZLIB_ROOT is not work, because policy CMP0074 is not set: find_package uses _ROOT variables.
Therefore I set cmake_policy command whitch is as follows:
cmake_policy(SET CMP0074 NEW)
set(ZLIB_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/zlib)
add_subdirectory(libpng)
add_subdirectory(zlib)
However, cmake_policy command is not work. An error which CMP0074 is not set has occured yet.
Related
I'm trying to cross compile some c++ library for QNX neutrino using cmake. In CMakeLists.txt file I specified CMAKE_CXX_STANDARD 14 required, but the resulting compiler command line does not contain the -std=c++14 option.
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
I've tried using target compile features:
target_compile_features(my_library PRIVATE cxx_std_14)
but that gives me the following error:
CMake Error at CMakeLists.txt:53 (target_compile_features):
target_compile_features no known features for CXX compiler
"QCC"
version 5.4.0.
When I'm using check_cxx_compiler_flag feature, it seems to recognize the option:
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-std=c++14 CXX14_SUPPORT)
if(CXX14_SUPPORT)
message("c++14 support found")
else()
message("c++14 unsupported")
endif()
This outputs message
c++14 support found
Running qcc manually it accepts the -std=c++14 option just fine and the code using std::make_unique compiles just fine.
Also using the native compiler (Ubuntu 18.04, gcc) everything work fine with cmake generated makefiles. make VERBOSE=1 displays the following command line (I removed some directories):
/usr/local/bin/c++ -Dshm_transfer_EXPORTS -I... -fPIC -std=gnu++14 -o CMakeFiles/shm_transfer.dir/src/SharedMemoryTransfer.cpp.o -c .../SharedMemoryTransfer.cpp
as opposed to the command line using qcc toolchain:
.../qnx700/host/linux/x86_64/usr/bin/qcc -lang-c++ -Vgcc_ntox86_64 -lang-c++ -Dshm_transfer_EXPORTS -I... -fPIC -o CMakeFiles/shm_transfer.dir/src/SharedMemoryTransfer.cpp.o -c .../SharedMemoryTransfer.cpp
I would have expected the cmake command to recognize that qcc supports the -std=c++14 option and generates the corresponding command lines because of the CMAKE_CXX_STANDARD setting.
Use
set_property(TARGET ${PROJECT_NAME} PROPERTY LINKER_LANGUAGE CXX)
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14)
. Using this you can stick the compiler setting to the target, while global flags are dis encouraged and can be overwritten by other cmake consumers. This the reason I assume why the deprecated set(CMAKE_CXX_STANDARD 14) did not help you: I can not see your full CMakeLists.txt and bet you have many sub folders and other targets, which could reset the CMAKE_CXX_STANDARD them selfs. Also make sure of the ordering of the CMake commands.
And you can replace ${PROJECT_NAME} with my_library if you want.
add_compile_options(-std=gnu++14)
Add this to your project level CMakeLists.txt file, not in toolchain.
I am using the FetchContent feature from CMake (3.12) and declaring it like this:
FetchContent_Declare(libsndfile
GIT_REPOSITORY ${LIBSNDFILE_GIT_REPO}
GIT_TAG ${LIBSNDFILE_GIT_TAG}
GIT_CONFIG advice.detachedHead=false
SOURCE_DIR "${CMAKE_BINARY_DIR}/libsndfile"
BINARY_DIR "${CMAKE_BINARY_DIR}/libsndfile-build"
CMAKE_ARGS "-Wno-dev"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
According to the CMake documentation:
FetchContent_Declare: The <contentOptions> can be any of the download or update/patch options that the ExternalProject_Add() command understands
And according to the ExternalProject_Add documentation, "The specified arguments are passed to the cmake command line" when using CMAKE_ARGS.
The -Wno-dev option does not seem to be passed along as I continue to see this warning messages in the output:
CMake Warning (dev) at /Volumes/Vault/misc/src/libsndfile/CMakeLists.txt:446 (add_executable):
Policy CMP0063 is not set: Honor visibility properties for all target
types. Run "cmake --help-policy CMP0063" for policy details. Use the
cmake_policy command to set the policy and suppress this warning.
Target "sndfile-interleave" of type "EXECUTABLE" has the following
visibility properties set for C:
C_VISIBILITY_PRESET
For compatibility CMake is not honoring them for this target.
This warning is for project developers. Use -Wno-dev to suppress it.
I believe I am following the documentation but it seems I must be doing something wrong. Any idea what could be wrong?
Edit: As requested in comment, here is a complete example:
File CMakeLists.txt
cmake_minimum_required(VERSION 3.12)
project(self_contained_libsndfile_example)
set(CMAKE_CXX_STANDARD 14)
# This is in order to trigger the warnings in FetchContent
set(CMAKE_C_VISIBILITY_PRESET hidden)
include(FetchContent)
set(LIBSNDFILE_GIT_REPO "https://github.com/erikd/libsndfile" CACHE STRING "libsndfile git repository url" FORCE)
set(LIBSNDFILE_GIT_TAG b4bd397ca74f4c72b9cabaae66fef0c3d5a8c527 CACHE STRING "libsndfile git tag" FORCE)
FetchContent_Declare(libsndfile
GIT_REPOSITORY ${LIBSNDFILE_GIT_REPO}
GIT_TAG ${LIBSNDFILE_GIT_TAG}
GIT_CONFIG advice.detachedHead=false
SOURCE_DIR "${CMAKE_BINARY_DIR}/libsndfile"
BINARY_DIR "${CMAKE_BINARY_DIR}/libsndfile-build"
CMAKE_ARGS "-Wno-dev"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
FetchContent_GetProperties(libsndfile)
if(NOT libsndfile_POPULATED)
FetchContent_Populate(libsndfile)
endif()
set(LIBSNDFILE_ROOT_DIR ${libsndfile_SOURCE_DIR})
set(LIBSNDFILE_INCLUDE_DIR "${libsndfile_BINARY_DIR}/src")
add_subdirectory(${libsndfile_SOURCE_DIR} ${libsndfile_BINARY_DIR} EXCLUDE_FROM_ALL)
file(COPY "${libsndfile_SOURCE_DIR}/src/sndfile.hh" DESTINATION ${LIBSNDFILE_INCLUDE_DIR})
include_directories(${LIBSNDFILE_INCLUDE_DIR})
set(target self_contained_libsndfile_example)
add_executable(${target} main.cpp)
target_link_libraries(${target} PRIVATE sndfile)
With the fix of this CMake-issue, which will go into CMake 3.17, you could point variable CMAKE_PROJECT_sndfile_INCLUDE_BEFORE to a file which sets the CMake-policy CMP0063 appropriately and which will automatically be included before the call to project(sndfile). As a result you won't get this warning for your fetched project.
This is a misunderstanding of the CMake documentation. The CMAKE_ARGS is part of the Configure Step options not download or update/patch options of the ExternalProject_Add() and is ignored.
Looking at the documentation for CMake (3.12) [https://cmake.org/cmake/help/v3.12/module/FetchContent.html]
The contentOptions can be any of the download or update/patch
options that the ExternalProject_Add() command understands. The
configure, build, install and test steps are explicitly disabled and
therefore options related to them will be ignored.
To avoid the messages you see you need to invoke cmake as cmake -Wno-dev on the command line when building your project.
I need to force my Cmake to build and link my MPI code with MPICH. My MPICH is installed using the Ubuntu Package manager, in a standard location /usr/lib/mpich/. However, CMake still looks for the OpenMPI libraries, which I do not use. How can I instruct CMake to look for MPICH instead?
Below, you can see the output of some basic diagnostics:
$ whereis openmpi
openmpi:
$ whereis mpich
mpich: /usr/lib/mpich /usr/include/mpich
$ mpicc -v
mpicc for MPICH version 3.2
Below, I also provide the Cmake script and the errors I get from cmake and the mpirun.mpich. My Cmake is 3.5.1 and I run on Ubuntu Xenial 16.04.
cmake_minimum_required(VERSION 3.0)
message (STATUS "Adding mpiService")
find_package(MPI REQUIRED)
set(CMAKE_C_COMPILER mpicc)
set(CMAKE_CXX_COMPILER mpicxx)
set(MPI_GUESS_LIBRARY_NAME MPICH2)
message(STATUS ${MPI_INCLUDE_PATH})
message(STATUS ${MPI_C_LIBRARIES})
#add_definitions(-DOMPI_SKIP_MPICXX)
add_executable(mpiService main.cpp)
set(CMAKE_VERBOSE_MAKEFILE ON)
include_directories(SYSTEM ${MPI_INCLUDE_PATH})
target_link_libraries(
mpiService
PRIVATE
${MPI_C_LIBRARIES}
)
From the Cmake STATUS I get the following output:
/usr/lib/openmpi/include/openmpi/opal/mca/event/libevent2021/libevent/usr/lib/openmpi/include/openmpi/opal/mca/event/libevent2021/libevent/include/usr/lib/openmpi/include/usr/lib/openmpi/include/openmpi
/usr/lib/openmpi/lib/libmpi.so
And when I run the binary I get the following:
ubuntu#node1:~$ mpirun.mpich -np 2 --host node1,node2 mpiService
mpiService: error while loading shared libraries: libmpi.so.12: cannot open shared object file: No such file or directory
mpiService: error while loading shared libraries: libmpi.so.12: cannot open shared object file: No such file or directory
How can I instruct CMake to look for MPICH instead?
According to FindMPI documentation, you may set MPI_<lang>_COMPILER variable to the desired MPI compiler:
Set MPI_<lang>_COMPILER to the MPI wrapper (mpicc, etc.) of your
choice and reconfigure. FindMPI will attempt to determine all the
necessary variables using THAT compiler's compile and link flags.
set(MPI_CXX_COMPILER <path-to-mpich-compiler>)
find_package(MPI REQUIRED)
Alternatively, since CMake version 3.10, variable MPI_EXECUTABLE_SUFFIX can be set instead:
A suffix which is appended to all names that are being looked for. For instance you may set this to .mpich or .openmpi to prefer the one or the other on Debian and its derivatives.
set(MPI_EXECUTABLE_SUFFIX ".mpich")
find_package(MPI REQUIRED)
Herewith my current solution.
find_package(MPI REQUIRED)
# ----------------
# This is the only thing that made it work
# ----------------
set(MPI_C_LIBRARIES "/usr/lib/mpich/lib/libmpich.so")
set(MPI_INCLUDE_PATH "/usr/include/mpich")
# ----------------
add_executable(mpiService main.cpp)
include_directories(SYSTEM ${MPI_INCLUDE_PATH})
target_link_libraries(
mpiService
${MPI_C_LIBRARIES}
)
I personally do not like this solution, as I have to explicitly specify the path. Any other proposed solution was still building with OpenMPI. If I find a better alternative, I will re-post.
Suppose CMAKE_BINARY_DIR = C://a//b//c, and if I run the following cmake script:
cmake_minimum_required( VERSION 2.6 )
set(project_name "hello_cmake")
project(${project_name})
add_executable(hello src/main.cpp)
if(WIN32)
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Installation Directory" )
else()
set(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "Installation Directory")
endif()
I expect CMAKE_INSTALL_PREFIX = C://a//b//c//install if I do not define CMAKE_INSTALL_PREFIX when I first call cmake .. from the folder C://a//b//c. However, it does not work in that way, and CMAKE_INSTALL_PREFIX is given a strange folder: C://Program Files (x86)//hello_cmake. Any ideas?
This is the recommended CMake incantation for handling CMAKE_INSTALL_PREFIX:
IF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
SET(CMAKE_INSTALL_PREFIX <path> CACHE PATH <comment> FORCE)
ENDIF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
Note the FORCE in the set. Apparently, the CMAKE_INSTALL_PREFIX is set fairly early in the invocation of CMake, which means it will already be set in the cache by the time you get to this line. Thus the need for FORCE.
Source is an email discussion on CMake mailing list: http://www.cmake.org/pipermail/cmake/2010-December/041135.html
I am trying to built a "Hello World" project with Qt 5 and cmake under MinGW.
This is the CMakeLists.txt file (taken from the on-line doc):
project(Qt5_cmake_test)
cmake_minimum_required(VERSION 2.8.11)
set(CMAKE_PREFIX_PATH "C:/Qt/Qt5.1.1/5.1.1/mingw48_32")
# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
# Find the QtWidgets library
find_package(Qt5Widgets)
# Add the source files from the current directory
aux_source_directory(. SRC_LIST)
# Tell CMake to create the executable
add_executable(${PROJECT_NAME} WIN32 ${SRC_LIST})
# Use the Widgets module from Qt5
target_link_libraries(${PROJECT_NAME} Qt5::Widgets)
The source code is the one generated automatically when creating a new project (which produces an empty window).
Configuring from the Windows command prompt with: cmake -G "MinGW Makefiles" ..\Qt5_cmake_test
I get these errors:
CMake Error at C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/CMakeMinGWFindMake.cmake:20 (message):
sh.exe was found in your PATH, here:
C:/Program Files (x86)/Git/bin/sh.exe
For MinGW make to work correctly sh.exe must NOT be in your path.
Run cmake from a shell that does not have sh.exe in your PATH.
If you want to use a UNIX shell, then use MSYS Makefiles.
Call Stack (most recent call first):
CMakeLists.txt:8 (project)
CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
Missing variable is:
CMAKE_C_COMPILER_ENV_VAR
CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
Missing variable is:
CMAKE_C_COMPILER
CMake Error: Could not find cmake module file:C:/Users/pietro.mele/projects/tests/buildSystem_test/Qt5_cmake_test-build/CMakeFiles/2.8.11.2/CMakeCCompiler.cmake
CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
Missing variable is:
CMAKE_CXX_COMPILER_ENV_VAR
CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
Missing variable is:
CMAKE_CXX_COMPILER
CMake Error: Could not find cmake module file:C:/Users/pietro.mele/projects/tests/buildSystem_test/Qt5_cmake_test-build/CMakeFiles/2.8.11.2/CMakeCXXCompiler.cma
ke
CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage
CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage
-- Configuring incomplete, errors occurred!
So it seems it is not able to find the compiler. Is there a way to let cmake find it on its own, or just giving it the CMAKE_PREFIX_PATH directory?
Do I have to manually specify all those variables in the makefile or as environment variables in Windows?
I tried both from the standard Windows command prompt and from the one provided by Qt, with the same result. Is it OK to build from the Windows command prompt, or should I do it from the MinGW's shell?
Platform:
Qt 5.1
CMake 2.8.11.2
MinGW/GCC 4.8
Windows 7
Get the git path out of your PATH before running cmake.
Here is the magic to do that:
set PATH=%PATH:C:/Program Files (x86)/Git/bin;=%
This CMakeLists.txt file works properly:
project(Qt5_cmake_test)
cmake_minimum_required(VERSION 2.8.11)
set(CMAKE_PREFIX_PATH "C:/Qt/Qt5.1.1/5.1.1/mingw48_32")
# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
# Find the Qt libraries
find_package(Qt5Core REQUIRED)
find_package(Qt5Widgets REQUIRED)
# Add the source files from the current directory
aux_source_directory(. SRC_LIST)
# Tell CMake to create the executable
add_executable(${PROJECT_NAME} WIN32 ${SRC_LIST})
# Use Qt5 modules
target_link_libraries(${PROJECT_NAME}
Qt5::Widgets
Qt5::WinMain)
The changes are:
Added find_package(Qt5Core REQUIRED).
Added Qt5::WinMain to target_link_libraries.
In some of my answer here on SO, I have described. CMake does not like sh.exe.
sh.exe was found in your PATH, here:
C:/Program Files (x86)/Git/bin/sh.exe
Solution : Rename C:/Program Files (x86)/Git/bin/sh.exe shortly.
For example:
C:/Program Files (x86)/Git/bin/shxx.exe
But do not forget when everything is built. rename properly again.