fortran defined macro ignored with cmake - cmake

I am trying to create a new macro in a Fortran file. Such file is one of many in a bigger project. It is compiled through a CMake file and gfortran.
For its simplicity I just included a simple example:
#define hello call
module SIO_ncDimBounds_mod
use SIO_ncParams_mod, only: MAX_DIMLEN_NAME
...
logical, parameter :: ISDEBUG = .false.
hello -> not recognized as Macro
When It is compiled it is ignored so it raises an error:
../soulio/src/ncDimBounds_mod.F90:34:2:
34 | hello
| 1
Error: Unclassifiable statement at (1)
As far as I understand, with upper case file extension should be enough to execute the preprocessor. I also checked the '-cpp' flag is enabled. I doubled checked with verbose mode to ensure it is enabled:
[ 22%] Building Fortran object src/CMakeFiles/soulio_lib.dir/ncDimBounds_mod.F90.o
cd ../soulio/build/src && /usr/bin/gfortran -DENABLE_MPI -I../projects/soulio/src/soulshared_lib -I../soulio/extern/Library/include -I/usr/lib/x86_64-linux-gnu/openmpi/include -I/usr/lib/x86_64-linux-gnu/openmpi/lib -ffree-form -std=f2008 -fimplicit-none -cpp -g -fbounds-check -pedantic -ffpe-trap=zero,invalid,overflow,underflow -O0 -Wall -fcheck=all -fbacktrace -Wextra --coverage -fprofile-arcs -ftest-coverage -J../../lib -c ../soulio/src/ncDimBounds_mod.F90 -o CMakeFiles/soulio_lib.dir/ncDimBounds_mod.F90.o
I also include the CMakeFile:
cmake_minimum_required(VERSION 3.9)
project(soulio)
enable_language(Fortran)
find_program(FYPP fypp)
if(NOT FYPP)
message(FATAL_ERROR "Preprocessor fypp could not be found")
endif()
# custom compiler flags
if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
set(dialect "-ffree-form -std=f2008 -fimplicit-none -cpp")
set(debugMode "-fbounds-check -pedantic -ffpe-trap=zero,invalid,overflow,underflow -O0 -Wall -fcheck=all -fbacktrace -Wextra")
set(optimizedMode "-ftree-vectorize" )
endif()
if(CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
set(dialect "-stand f08 -free -implicitnone")
set(debugMode "-check bounds")
set(optimizedMode "-O3 -xHost")
endif()
if(CMAKE_Fortran_COMPILER_ID MATCHES "PGI")
set(dialect "-Mfreeform -Mdclchk -Mstandard -Mallocatable=03")
set(debugMode "-C")
set(optimizedMode "")
endif()
set(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} ${optimizedMode}")
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} ${debugMode}")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${dialect}")
# Place lib and binary files
# dynamic libraries
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
# static library
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
# target files
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
# Have the .mod files placed in the lib folder
SET(LIB ${CMAKE_SOURCE_DIR}/lib)
SET(CMAKE_Fortran_MODULE_DIRECTORY ${LIB})
# include cmake modules
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
include(soulioUtils)
message(status ${CMAKE_SOURCE_DIR})
# call for netcdf library
if (NOT HAS_SOULSM)
set (NETCDF_C "YES")
set (NETCDF_F90 "YES")
set (NETCDF_INCLUDES ${CMAKE_SOURCE_DIR}/extern/Library/include)
set (NETCDF_INCLUDES_C ${CMAKE_SOURCE_DIR}/extern/Library/include)
set (NETCDF_INCLUDES_F77 ${CMAKE_SOURCE_DIR}/extern/Library/include)
set (NETCDF_INCLUDES_F90 ${CMAKE_SOURCE_DIR}/extern/Library/include)
set (NETCDF_INCLUDES_CXX ${CMAKE_SOURCE_DIR}/extern/Library/include)
set (NETCDF_LIBRARIES_F77 ${CMAKE_SOURCE_DIR}/extern/Library/lib/libnetcdff.so)
set (NETCDF_LIBRARIES_F90 ${CMAKE_SOURCE_DIR}/extern/Library/lib/libnetcdff.so)
set (NETCDF_LIBRARIES_C ${CMAKE_SOURCE_DIR}/extern/Library/lib/libnetcdf.so)
set (NETCDF_LIBRARIES ${CMAKE_SOURCE_DIR}/extern/Library/lib/libnetcdf.so)
find_package (NetCDF REQUIRED)
endif()
if (ENABLE_MPI)
find_package (MPI REQUIRED)
add_definitions(-DENABLE_MPI)
endif()
message(STATUS "Run: ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS")
if(BUILD_TESTING)
enable_testing()
SET( CMAKE_BUILD_TYPE Debug )
include( cmake/CodeCoverage.cmake )
SET(coverageMode "--coverage -fprofile-arcs -ftest-coverage")
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} ${coverageMode}")
add_subdirectory(tests)
endif()
if (NOT HAS_SOULSM)
add_subdirectory(soulshared)
endif()
add_subdirectory(src)
I did a simple and isolated test with a fortran file with an uppercase extension, as expected it works.
Why is the macro not replaced with CMake? It seems to me the preprocessor it is not called.
Edit:
'hello' is changed to lowercase

If we change the example to
subroutine silly()
print *, 'It works'
return
end subroutine silly
#define hello call
program main
hello silly
stop
end program main
and build using
gfortran -cpp macro.f90
This builds without any problems. If I just have hello on its own, then I get a syntax error.
First, make sure your program is valid. call on its own will generate an error. You need to call something.
Could you try building without cmake? If it works without cmake and doesn't work with cmake then it is a cmake problem. Otherwise, you just have a problem with your code.

Related

How to turn on optimizations ( O3 ) when invoking cmake?

I am trying to build mlpack from source,
So far I have compiled the library with the below command,
cmake -G "MinGW Makefiles" -DBoost_INCLUDE_DIR="C:\msys64\mingw64\include" -DBUILD_BINDINGS=OFF -DARMADILLO_INCLUDE_DIR="C:\Users\Shoyeb\Downloads\armadillo-11.0.1.tar\armadillo-11.0.1\include"
when I invoked mingw32-make,
I got the below error,
Error says file too big.
How to invoke cmake with optimization flags like O3,
Below are the contents of CMakeLists.txt,
cmake_minimum_required(VERSION 3.3.2)
project(mlpack C CXX)
include(CMake/cotire.cmake)
include(CMake/CheckHash.cmake)
# First, define all the compilation options.
# We default to debugging mode for developers.
option(DEBUG "Compile with debugging information." OFF)
option(PROFILE "Compile with profiling information." OFF)
option(ARMA_EXTRA_DEBUG "Compile with extra Armadillo debugging symbols." OFF)
option(MATLAB_BINDINGS "Compile MATLAB bindings if MATLAB is found." OFF)
option(TEST_VERBOSE "Run test cases with verbose output." OFF)
option(BUILD_TESTS "Build tests." ON)
option(BUILD_CLI_EXECUTABLES "Build command-line executables." ON)
option(DISABLE_DOWNLOADS "Disable downloads of dependencies during build." OFF)
option(DOWNLOAD_ENSMALLEN "If ensmallen is not found, download it." ON)
option(DOWNLOAD_STB_IMAGE "Download stb_image for image loading." ON)
option(BUILD_GO_SHLIB "Build Go shared library." OFF)
# Set minimum library version required by mlpack.
set(ARMADILLO_VERSION "8.400.0")
set(ENSMALLEN_VERSION "2.10.0")
set(BOOST_VERSION "1.58")
if (WIN32)
option(BUILD_SHARED_LIBS
"Compile shared libraries (if OFF, static libraries are compiled)." OFF)
set(DLL_COPY_DIRS "" CACHE STRING "List of directories (separated by ';') containing DLLs to copy for runtime.")
set(DLL_COPY_LIBS "" CACHE STRING "List of DLLs (separated by ';') that should be copied for runtime.")
else ()
option(BUILD_SHARED_LIBS
"Compile shared libraries (if OFF, static libraries are compiled)." ON)
endif()
# Detect whether the user passed BUILD_PYTHON_BINDINGS in order to determine if
# we should fail if Python isn't found.
if (BUILD_PYTHON_BINDINGS)
set(FORCE_BUILD_PYTHON_BINDINGS ON)
else()
set(FORCE_BUILD_PYTHON_BINDINGS OFF)
endif()
option(BUILD_PYTHON_BINDINGS "Build Python bindings." OFF)
# Detect whether the user passed BUILD_JULIA_BINDINGS in order to determine if
# we should fail if Julia isn't found.
if (BUILD_JULIA_BINDINGS)
set(FORCE_BUILD_JULIA_BINDINGS ON)
else()
set(FORCE_BUILD_JULIA_BINDINGS OFF)
endif()
option(BUILD_JULIA_BINDINGS "Build Julia bindings." ON)
# Detect whether the user passed BUILD_GO_BINDINGS in order to determine if
# we should fail if Go isn't found.
if (BUILD_GO_BINDINGS)
set(FORCE_BUILD_GO_BINDINGS ON)
else()
set(FORCE_BUILD_GO_BINDINGS OFF)
endif()
option(BUILD_GO_BINDINGS "Build Go bindings." ON)
# If building Go bindings then build go shared libraries.
if (BUILD_GO_BINDINGS)
set(BUILD_GO_SHLIB ON)
endif()
# Detect whether the user passed BUILD_R_BINDINGS in order to determine if
# we should fail if R isn't found.
if (BUILD_R_BINDINGS)
set(FORCE_BUILD_R_BINDINGS ON)
else()
set(FORCE_BUILD_R_BINDINGS OFF)
endif()
option(BUILD_R_BINDINGS "Build R bindings." ON)
# Build Markdown bindings for documentation. This is used as part of website
# generation.
option(BUILD_MARKDOWN_BINDINGS "Build Markdown bindings for website documentation." OFF)
option(BUILD_WITH_COVERAGE
"Build with support for code coverage tools (gcc only)." OFF)
option(MATHJAX
"Use MathJax for HTML Doxygen output (disabled by default)." OFF)
option(FORCE_CXX11
"Don't check that the compiler supports C++11, just assume it. Make sure to specify any necessary flag to enable C++11 as part of CXXFLAGS." OFF)
option(USE_OPENMP "If available, use OpenMP for parallelization." ON)
enable_testing()
# Set required standard to C++11.
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Include modules in the CMake directory.
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMake")
# Disable any downloads if needed.
if (DISABLE_DOWNLOADS)
set(DOWNLOAD_ENSMALLEN OFF)
set(DOWNLOAD_STB_IMAGE OFF)
endif ()
# If we are on a Unix-like system, use the GNU install directories module.
# Otherwise set the values manually.
if (UNIX)
include(GNUInstallDirs)
else ()
set(CMAKE_INSTALL_BINDIR ${CMAKE_INSTALL_PREFIX}/bin)
set(CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX}/lib)
set(CMAKE_INSTALL_MANDIR ${CMAKE_INSTALL_PREFIX}/man)
set(CMAKE_INSTALL_DOCDIR ${CMAKE_INSTALL_PREFIX}/share/doc/mlpack)
set(CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX}/include)
endif ()
# This is as of yet unused.
#option(PGO "Use profile-guided optimization if not a debug build" ON)
# Set the CFLAGS and CXXFLAGS depending on the options the user specified.
# Only GCC-like compilers support -Wextra, and other compilers give tons of
# output for -Wall, so only -Wall and -Wextra on GCC.
if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# Ensure that we can't compile with clang 3.4, since this causes strange
# issues.
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)
message(FATAL_ERROR "mlpack does not build correctly with clang < 3.5. "
"Please upgrade your compiler and reconfigure mlpack.")
endif ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -ftemplate-depth=1000")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
# To remove unused functions warnings.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-function")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
endif()
# These support libraries are used if we need to link against something
# specific. This list is a subset of MLPACK_LIBRARIES.
set(COMPILER_SUPPORT_LIBRARIES "")
# If we are using MSVC, we need /bigobj.
if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
endif ()
# If we are using MINGW, we need sections and big-obj, otherwise we create too
# many sections.
if(CMAKE_COMPILER_IS_GNUCC AND WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections -Wa,-mbig-obj")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections -Wa,-mbig-obj")
endif()
# If using clang, we have to link against libc++ depending on the
# OS (at least on some systems). Further, gcc sometimes optimizes calls to
# math.h functions, making -lm unnecessary with gcc, but it may still be
# necessary with clang.
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
if (APPLE)
# Detect OS X version. Use '/usr/bin/sw_vers -productVersion' to
# extract V from '10.V.x'.
exec_program(/usr/bin/sw_vers ARGS
-productVersion OUTPUT_VARIABLE MACOSX_VERSION_RAW)
string(REGEX REPLACE
"10\\.([0-9]+).*" "\\1"
MACOSX_VERSION
"${MACOSX_VERSION_RAW}")
# OSX Lion (10.7) and OS X Mountain Lion (10.8) doesn't automatically
# select the right stdlib.
if(${MACOSX_VERSION} LESS 9)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++")
set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -stdlib=libc++")
set(CMAKE_MODULE_LINKER_FLAGS
"${CMAKE_MODULE_LINKER_FLAGS} -stdlib=libc++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
endif()
# Link everything with -lm.
set(COMPILER_SUPPORT_LIBRARIES ${COMPILER_SUPPORT_LIBRARIES} "m")
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} "m")
# Use -pthread, but not on OS X.
if (NOT APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
endif ()
endif()
# If we're using gcc, then we need to link against pthreads to use std::thread,
# which we do in the tests.
if(CMAKE_COMPILER_IS_GNUCC)
find_package(Threads)
set(COMPILER_SUPPORT_LIBRARIES ${COMPILER_SUPPORT_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT})
endif()
# Setup build for test coverage
if(BUILD_WITH_COVERAGE)
# Currently coverage only works with GNU g++.
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# Find gcov and lcov
find_program(GCOV gcov)
find_program(LCOV lcov)
if(NOT GCOV)
message(FATAL_ERROR
"gcov not found! gcov is required when BUILD_WITH_COVERAGE=ON.")
endif()
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} "supc++")
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} "quadmath")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -fno-inline -fno-inline-small-functions -fno-default-inline -fprofile-arcs -fkeep-inline-functions")
message(STATUS "Adding debug compile options for code coverage.")
# Remove optimizations for better line coverage
set(DEBUG ON)
if(LCOV)
configure_file(CMake/mlpack_coverage.in mlpack_coverage #ONLY)
add_custom_target(mlpack_coverage DEPENDS mlpack_test COMMAND ${PROJECT_BINARY_DIR}/mlpack_coverage)
else()
message(WARNING "'lcov' not found; local coverage report is disabled. "
"Install 'lcov' and rerun cmake to generate local coverage report.")
endif()
else()
message(FATAL_ERROR "BUILD_WITH_COVERAGE can only work with GNU environment.")
endif()
endif()
# Debugging CFLAGS. Turn optimizations off; turn debugging symbols on.
if(DEBUG)
if (NOT MSVC)
add_definitions(-DDEBUG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -ftemplate-backtrace-limit=0")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -g -O0")
endif()
# mlpack uses it's own mlpack::backtrace class based on Binary File Descriptor
# <bfd.h> and linux Dynamic Loader <libdl.h> and more portable version in future
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
find_package(Bfd)
find_package(LibDL)
if(LIBBFD_FOUND AND LIBDL_FOUND)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic")
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${LIBBFD_INCLUDE_DIRS}
${LIBDL_INCLUDE_DIRS})
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} ${LIBBFD_LIBRARIES}
${LIBDL_LIBRARIES})
add_definitions(-DHAS_BFD_DL)
else()
message(WARNING "No libBFD and/or libDL has been found!")
endif()
endif()
else()
add_definitions(-DARMA_NO_DEBUG)
add_definitions(-DNDEBUG)
if (NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -O3")
else ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O3")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /O3")
endif ()
endif()
# Profiling CFLAGS. Turn profiling information on.
if(CMAKE_COMPILER_IS_GNUCC AND PROFILE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pg")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg")
endif()
# If the user asked for running test cases with verbose output, turn that on.
if(TEST_VERBOSE)
add_definitions(-DTEST_VERBOSE)
endif()
# If the user asked for extra Armadillo debugging output, turn that on.
if(ARMA_EXTRA_DEBUG)
add_definitions(-DARMA_EXTRA_DEBUG)
endif()
# Now, find the libraries we need to compile against. Several variables can be
# set to manually specify the directory in which each of these libraries
# resides.
# ARMADILLO_LIBRARY - location of libarmadillo.so / armadillo.lib
# ARMADILLO_INCLUDE_DIR - directory containing <armadillo>
# ARMADILLO_INCLUDE_DIRS - directories necessary for Armadillo includes
# BOOST_ROOT - root of Boost installation
# BOOST_INCLUDEDIR - include directory for Boost
# BOOST_LIBRARYDIR - library directory for Boost
# ENSMALLEN_INCLUDE_DIR - include directory for ensmallen
# STB_IMAGE_INCLUDE_DIR - include directory for STB image library
# MATHJAX_ROOT - root of MathJax installation
find_package(Armadillo "${ARMADILLO_VERSION}" REQUIRED)
# Include directories for the previous dependencies.
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${ARMADILLO_INCLUDE_DIRS})
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} ${ARMADILLO_LIBRARIES})
# Find stb_image.h and stb_image_write.h.
find_package(StbImage)
# Download stb_image for image loading.
if (NOT STB_IMAGE_FOUND)
if (DOWNLOAD_STB_IMAGE)
set(STB_DIR "stb")
install(DIRECTORY DESTINATION "${CMAKE_BINARY_DIR}/deps/${STB_DIR}")
file(DOWNLOAD http://mlpack.org/files/stb-2.22/stb_image.h
"${CMAKE_BINARY_DIR}/deps/${STB_DIR}/stb_image.h"
STATUS STB_IMAGE_DOWNLOAD_STATUS_LIST LOG STB_IMAGE_DOWNLOAD_LOG
SHOW_PROGRESS)
list(GET STB_IMAGE_DOWNLOAD_STATUS_LIST 0 STB_IMAGE_DOWNLOAD_STATUS)
file(DOWNLOAD http://mlpack.org/files/stb-1.13/stb_image_write.h
"${CMAKE_BINARY_DIR}/deps/${STB_DIR}/stb_image_write.h"
STATUS STB_IMAGE_WRITE_DOWNLOAD_STATUS_LIST
LOG STB_IMAGE_WRITE_DOWNLOAD_LOG
SHOW_PROGRESS)
list(GET STB_IMAGE_WRITE_DOWNLOAD_STATUS_LIST 0
STB_IMAGE_WRITE_DOWNLOAD_STATUS)
if (STB_IMAGE_DOWNLOAD_STATUS EQUAL 0 AND
STB_IMAGE_WRITE_DOWNLOAD_STATUS EQUAL 0)
check_hash (http://mlpack.org/files/stb/hash.md5 "${CMAKE_BINARY_DIR}/deps/${STB_DIR}"
HASH_CHECK_FAIL)
if (HASH_CHECK_FAIL EQUAL 0)
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS}
"${CMAKE_BINARY_DIR}/deps/${STB_DIR}/")
message(STATUS
"Successfully downloaded stb into ${CMAKE_BINARY_DIR}/deps/${STB_DIR}/")
# Now we have to also ensure these header files get installed.
install(FILES "${CMAKE_BINARY_DIR}/deps/${STB_DIR}/stb_image.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(FILES "${CMAKE_BINARY_DIR}/deps/${STB_DIR}/stb_image_write.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
add_definitions(-DHAS_STB)
set(STB_AVAILABLE "1")
else ()
message(WARNING
"stb/stb_image.h is not installed. Image utilities will not be available!")
endif ()
else ()
file(REMOVE_RECURSE "${CMAKE_BINARY_DIR}/deps/${STB_DIR}/")
list(GET STB_IMAGE_DOWNLOAD_STATUS_LIST 1 STB_DOWNLOAD_ERROR)
message(WARNING
"Could not download stb! Error code ${STB_DOWNLOAD_STATUS}: ${STB_DOWNLOAD_ERROR}! Error log: ${STB_DOWNLOAD_LOG}")
message(WARNING
"stb/stb_image.h is not installed. Image utilities will not be available!")
endif ()
else ()
message(WARNING
"stb/stb_image.h is not installed. Image utilities will not be available!")
endif ()
else ()
# Already has STB installed.
add_definitions(-DHAS_STB)
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${STB_IMAGE_INCLUDE_DIR})
set(STB_AVAILABLE "1")
endif ()
# Find ensmallen.
# Once ensmallen is readily available in package repos, the automatic downloader
# here can be removed.
find_package(Ensmallen "${ENSMALLEN_VERSION}")
if (NOT ENSMALLEN_FOUND)
if (DOWNLOAD_ENSMALLEN)
file(DOWNLOAD http://www.ensmallen.org/files/ensmallen-2.14.2.tar.gz
"${CMAKE_BINARY_DIR}/deps/ensmallen-2.14.2.tar.gz"
STATUS ENS_DOWNLOAD_STATUS_LIST LOG ENS_DOWNLOAD_LOG
SHOW_PROGRESS)
list(GET ENS_DOWNLOAD_STATUS_LIST 0 ENS_DOWNLOAD_STATUS)
if (ENS_DOWNLOAD_STATUS EQUAL 0)
execute_process(COMMAND ${CMAKE_COMMAND} -E
tar xzf "${CMAKE_BINARY_DIR}/deps/ensmallen-2.14.2.tar.gz"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/deps/")
# Get the name of the directory.
file (GLOB ENS_DIRECTORIES RELATIVE "${CMAKE_BINARY_DIR}/deps/"
"${CMAKE_BINARY_DIR}/deps/ensmallen-[0-9]*.[0-9]*.[0-9]*")
# list(FILTER) is not available on 3.5 or older, but try to keep
# configuring without filtering the list anyway (it might work if only
# the file ensmallen-2.14.2.tar.gz is present.
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.6.0")
list(FILTER ENS_DIRECTORIES EXCLUDE REGEX "ensmallen-.*\.tar\.gz")
endif ()
list(LENGTH ENS_DIRECTORIES ENS_DIRECTORIES_LEN)
if (ENS_DIRECTORIES_LEN EQUAL 1)
list(GET ENS_DIRECTORIES 0 ENSMALLEN_INCLUDE_DIR)
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS}
"${CMAKE_BINARY_DIR}/deps/${ENSMALLEN_INCLUDE_DIR}/include")
message(STATUS
"Successfully downloaded ensmallen into ${CMAKE_BINARY_DIR}/deps/${ENSMALLEN_INCLUDE_DIR}/")
# Now we have to also ensure these header files get installed.
install(DIRECTORY "${CMAKE_BINARY_DIR}/deps/${ENSMALLEN_INCLUDE_DIR}/include/ensmallen_bits/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/ensmallen_bits")
install(FILES "${CMAKE_BINARY_DIR}/deps/${ENSMALLEN_INCLUDE_DIR}/include/ensmallen.hpp" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
else ()
message(FATAL_ERROR "Problem unpacking ensmallen! Expected only one directory ensmallen-x.y.z/; found ${ENS_DIRECTORIES}. Try removing the directory ${CMAKE_BINARY_DIR}/deps and reconfiguring.")
endif ()
else ()
list(GET ENS_DOWNLOAD_STATUS_LIST 1 ENS_DOWNLOAD_ERROR)
message(FATAL_ERROR
"Could not download ensmallen! Error code ${ENS_DOWNLOAD_STATUS}: ${ENS_DOWNLOAD_ERROR}! Error log: ${ENS_DOWNLOAD_LOG}")
endif ()
else ()
if (EXISTS "${CMAKE_SOURCE_DIR}/src/mlpack/core/optimizers/ensmallen/ensmallen.hpp")
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${ARMADILLO_INCLUDE_DIRS}
"${CMAKE_SOURCE_DIR}/src/mlpack/core/optimizers/ensmallen")
else ()
message(FATAL_ERROR
"Cannot find ensmallen headers! Try setting ENSMALLEN_INCLUDE_DIR!")
endif ()
endif ()
else ()
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} "${ENSMALLEN_INCLUDE_DIR}")
endif ()
set(Boost_ADDITIONAL_VERSIONS
"1.74.0" "1.74"
"17.3.0" "17.3"
"1.72.0" "1.72"
"1.71.0" "1.71"
"1.70.0" "1.70"
"1.69.0" "1.69"
"1.68.0" "1.68"
"1.67.0" "1.67"
"1.66.0" "1.66"
"1.65.1" "1.65.0" "1.65"
"1.64.1" "1.64.0" "1.64"
"1.63.1" "1.63.0" "1.63"
"1.62.1" "1.62.0" "1.62"
"1.61.1" "1.61.0" "1.61"
"1.60.1" "1.60.0" "1.60"
"1.59.1" "1.59.0" "1.59"
"1.58.1" "1.58.0" "1.58")
set(Boost_NO_BOOST_CMAKE 1)
find_package(Boost "${BOOST_VERSION}"
COMPONENTS
unit_test_framework
serialization
REQUIRED
)
link_directories(${Boost_LIBRARY_DIRS})
if (MSVC)
link_directories(${Boost_LIBRARY_DIRS})
set(CMAKE_MSVCIDE_RUN_PATH ${CMAKE_MSVCIDE_RUN_PATH} ${Boost_LIBRARY_DIRS})
message("boost lib dirs ${Boost_LIBRARY_DIRS}")
set(Boost_LIBRARIES "")
endif ()
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} ${Boost_LIBRARIES})
set(MLPACK_LIBRARY_DIRS ${MLPACK_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS})
add_definitions(-DBOOST_TEST_DYN_LINK)
if (USE_OPENMP)
find_package(OpenMP)
endif ()
if (OPENMP_FOUND)
add_definitions(-DHAS_OPENMP)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
else ()
# Disable warnings for all the unknown OpenMP pragmas.
if (NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas")
else ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4068")
endif ()
set(OpenMP_CXX_FLAGS "")
endif ()
include(CMake/TargetDistclean.cmake OPTIONAL)
include_directories(BEFORE ${MLPACK_INCLUDE_DIRS})
include_directories(BEFORE ${CMAKE_SOURCE_DIR}/src/)
# On Windows, things end up under Debug/ or Release/.
if (WIN32)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
foreach(dir ${DLL_COPY_DIRS})
file(GLOB dir_dll_list "${dir}/*.dll")
file(COPY ${dir_dll_list} DESTINATION ${CMAKE_BINARY_DIR}/Release/)
file(COPY ${dir_dll_list} DESTINATION ${CMAKE_BINARY_DIR}/Debug/)
endforeach ()
foreach(file ${DLL_COPY_LIBS})
file(COPY ${file} DESTINATION ${CMAKE_BINARY_DIR}/Release/)
file(COPY ${file} DESTINATION ${CMAKE_BINARY_DIR}/Debug/)
endforeach()
else ()
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/)
endif ()
find_package(Git)
set (USING_GIT "NO")
if (GIT_FOUND)
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE MLPACK_TMP_REV_INFO
ERROR_VARIABLE MLPACK_TMP_REV_INFO_ERROR
RESULT_VARIABLE MLPACK_TMP_REV_INFO_RESULT
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (${MLPACK_TMP_REV_INFO_RESULT} EQUAL 0)
set (USING_GIT "YES")
add_definitions(-DMLPACK_GIT_VERSION)
include(CMake/CreateGitVersionHeader.cmake)
add_custom_target(mlpack_gitversion ALL
COMMAND ${CMAKE_COMMAND} -P CMake/CreateGitVersionHeader.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Updating gitversion.hpp (if necessary)")
# Add gitversion.hpp to the list of sources.
set(MLPACK_SRCS ${MLPACK_SRCS}
"${CMAKE_CURRENT_SOURCE_DIR}/src/mlpack/core/util/gitversion.hpp")
endif ()
endif ()
include(CMake/CreateArmaConfigInfo.cmake)
add_custom_target(mlpack_arma_config ALL
COMMAND ${CMAKE_COMMAND}
-D ARMADILLO_INCLUDE_DIR="${ARMADILLO_INCLUDE_DIR}"
-D OPENMP_FOUND="${OPENMP_FOUND}"
-D CMAKE_SIZEOF_VOID_P="${CMAKE_SIZEOF_VOID_P}"
-P CMake/CreateArmaConfigInfo.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Updating arma_config.hpp (if necessary)")
set(MLPACK_SRCS ${MLPACK_SRCS}
"${CMAKE_CURRENT_SOURCE_DIR}/src/mlpack/core/util/arma_config.hpp")
if (BUILD_CLI_EXECUTABLES AND UNIX)
find_program(TXT2MAN txt2man)
# It's not a requirement that we make man pages.
if (NOT TXT2MAN)
message(WARNING "txt2man not found; man pages will not be generated.")
else ()
# We have the tools. We can make them.
add_custom_target(man ALL
${CMAKE_CURRENT_SOURCE_DIR}/CMake/allexec2man.sh
${CMAKE_CURRENT_SOURCE_DIR}/CMake/exec2man.sh
${CMAKE_BINARY_DIR}/share/man
WORKING_DIRECTORY
${CMAKE_BINARY_DIR}/bin
COMMENT "Generating man pages from built executables."
)
# Set the rules to install the documentation.
install(DIRECTORY "${CMAKE_BINARY_DIR}/share/man/"
DESTINATION "${CMAKE_INSTALL_MANDIR}")
endif ()
endif ()
# Recurse into the rest of the project.
add_subdirectory(src/mlpack)
if (USING_GIT STREQUAL "YES")
add_dependencies(mlpack_headers mlpack_gitversion)
endif ()
add_dependencies(mlpack_headers mlpack_arma_config)
find_package(Doxygen)
if (DOXYGEN_FOUND)
if (MATHJAX)
find_package(MathJax)
if (NOT MATHJAX_FOUND)
message(STATUS "Using MathJax at the MathJax Content Delivery Network. "
"Be careful, formulas will not be shown without the internet.")
endif ()
endif ()
# Preprocess the Doxyfile. This is done before 'make doc'.
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/Doxyfile
PRE_BUILD
COMMAND ${CMAKE_COMMAND}
-D DESTDIR=${CMAKE_BINARY_DIR}
-D MATHJAX="${MATHJAX}"
-D MATHJAX_FOUND="${MATHJAX_FOUND}"
-D MATHJAX_PATH="${MATHJAX_PATH}"
-P "${CMAKE_CURRENT_SOURCE_DIR}/CMake/GenerateDoxyfile.cmake"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile"
COMMENT "Creating Doxyfile to generate Doxygen documentation"
)
# Generate documentation.
add_custom_target(doc
COMMAND "${DOXYGEN_EXECUTABLE}" "${CMAKE_BINARY_DIR}/Doxyfile"
DEPENDS "${CMAKE_BINARY_DIR}/Doxyfile"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMENT "Generating API documentation with Doxygen"
)
install(DIRECTORY "${CMAKE_BINARY_DIR}/doc/html"
DESTINATION "${CMAKE_INSTALL_DOCDIR}"
COMPONENT doc
OPTIONAL
)
endif ()
# Create the pkg-config file, if we have pkg-config.
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
list(REMOVE_DUPLICATES MLPACK_INCLUDE_DIRS)
foreach (incldir ${MLPACK_INCLUDE_DIRS})
# Filter out some obviously unnecessary directories.
if (NOT "${incldir}" STREQUAL "/usr/include")
set(MLPACK_INCLUDE_DIRS_STRING
"${MLPACK_INCLUDE_DIRS_STRING} -I${incldir}")
endif ()
endforeach ()
# Add the install directory too.
set(MLPACK_INCLUDE_DIRS_STRING
"${MLPACK_INCLUDE_DIRS_STRING} -I${CMAKE_INSTALL_PREFIX}/include/")
# Create the list of link directories.
set(MLPACK_LIBRARIES_LIST)
foreach (linkdir ${MLPACK_LIBRARY_DIRS})
list(APPEND MLPACK_LIBRARIES_LIST "-L${linkdir}")
endforeach ()
foreach(lib ${MLPACK_LIBRARIES})
string(SUBSTRING "${lib}" 0 1 first)
if ("${first}" STREQUAL "/")
# We need to split the directory and the library.
string(REGEX REPLACE "(.*/)[^/]*$" "\\1" library_dir "${lib}")
string(REGEX REPLACE ".*/lib([^/]*)[.][a-z]*[.]*$" "\\1" library_name "${lib}")
list(APPEND MLPACK_LIBRARIES_LIST "-L${library_dir}")
list(APPEND MLPACK_LIBRARIES_LIST "-l${library_name}")
else ()
list(APPEND MLPACK_LIBRARIES_LIST "-l${lib}")
endif ()
endforeach ()
# Don't forget to add mlpack as a dependency too.
list(APPEND MLPACK_LIBRARIES_LIST "-L${CMAKE_INSTALL_PREFIX}/lib/")
list(APPEND MLPACK_LIBRARIES_LIST "-lmlpack")
# Filter duplicate dependencies and directories.
list(REMOVE_DUPLICATES MLPACK_LIBRARIES_LIST)
# Filter out known unnecessary directories.
list(REMOVE_ITEM MLPACK_LIBRARIES_LIST
"-L/usr/lib"
"-L/usr/lib/"
"-L/usr/lib/x86_64-linux-gnu"
"-L/usr/lib/x86_64-linux-gnu/"
"-L/usr/lib/i386-linux-gnu"
"-L/usr/lib/i386-linux-gnu/")
string(REPLACE ";" " " MLPACK_LIBRARIES_STRING "${MLPACK_LIBRARIES_LIST}")
# Do first stage of configuration.
set(MLPACK_VERSION_STRING "#MLPACK_VERSION_STRING#")
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/CMake/mlpack.pc.in
${CMAKE_BINARY_DIR}/CMake/mlpack.pc.in.partial #ONLY)
add_custom_target(pkgconfig ALL
${CMAKE_COMMAND}
-P "${CMAKE_CURRENT_SOURCE_DIR}/CMake/GeneratePkgConfig.cmake"
DEPENDS mlpack_headers
COMMENT "Generating mlpack.pc (pkg-config) file.")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/lib/pkgconfig/mlpack.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig/")
endif ()
Tried below command,
cmake -G "MinGW Makefiles" -DBoost_INCLUDE_DIR="C:\msys64\mingw64\include" -DBUILD_BINDINGS=OFF -DARMADILLO_INCLUDE_DIR="C:\Users\Shoyeb\Downloads\armadillo-11.0.1.tar\armadillo-11.0.1\include" -O3
Gives error,
CMake Error: Unknown argument -O3
You can add it via the cmake run like this:
cmake -G "MinGW Makefiles" -DCMAKE_CXX_FLAGS=-O3
But looks like you really don't need to do provide anything at all as the script you have already adds -O3 if you don't turn the DEBUG option on, which you don't (at least in the post).

Add a compilation option right before the filename of the source with cmake

I have received a code written in Fortran with files named using extension .f95. I know that this extension is not recommended, one should only use .f for fixed form Fortran and .f90 for free form Fortran, but this is the way I received the code.
I have prepared some cmake files in order to compile it. It works well when I use gfortran but it does not when I use Intel Fortran 2021. It seems that Intel Fortran does not accept .f95 extensions by default.
For example, the following does not work:
ifort mySrc.f95 -c
But one can force ifort to accept this .f95 extension by typing:
ifort -free -Tf mySrc.f95 -c
This is a simplified CMakeLists.txt I have prepared for the project:
cmake_minimum_required(VERSION 3.12)
project (Test VERSION 1.0
DESCRIPTION "CMAKE files to compile test"
LANGUAGES Fortran)
if (CMAKE_Fortran_COMPILER_ID STREQUAL "Intel")
if(CMAKE_Fortran_COMPILER_VERSION VERSION_LESS "20")
message(FATAL_ERROR "Intel Fortran Compiler 20 or newer required")
endif()
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -warn all")
set (CMAKE_Fortran_FLAGS_RELEASE "-O2")
set (CMAKE_Fortran_FLAGS_RELWITHDEBINFO "-O2 -g")
set (CMAKE_Fortran_FLAGS_DEBUG "-g")
endif()
file(GLOB FILES_SRC CONFIGURE_DEPENDS "*.f95")
set(LIB_MOD_DIR ${CMAKE_CURRENT_BINARY_DIR}/mod/)
add_executable(MYCODE ${FILES_SRC})
set_target_properties(MYCODE
PROPERTIES Fortran_MODULE_DIRECTORY ${LIB_MOD_DIR})
set_property(TARGET MYCODE PROPERTY LINKER_LANGUAGE Fortran)
install(TARGETS MYCODE
RUNTIME DESTINATION bin
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
)
install(DIRECTORY ${LIB_MOD_DIR} DESTINATION include)
I am trying to add these -free and -Tf options to my cmake scripts, but these options must go right before the filename of the file to compile. I have found this link where they mention that this can be achieved my modifying file /Modules/Platform/Linux-Intel-Fortran.cmake. However, I do not have privileges to modify that file. I have tried adding the following to my CMakeLists.txt right after the endif():
SET(CMAKE_Fortran_COMPILE_OBJECT "<CMAKE_Fortran_COMPILER> -o <OBJECT> <DEFINES> <FLAGS> -c -Tf <SOURCE>")
but I keep getting errors. Is it possible to implement this using the CMakeLists.txt file? Thanks in advance.
When I was adding the following option in the CMakeLists.txt file:
SET(CMAKE_Fortran_COMPILE_OBJECT "<CMAKE_Fortran_COMPILER> -o <OBJECT> <DEFINES> <FLAGS> -c -Tf <SOURCE>")
I forgot to add -free to indicate that the files are in free form format. By default -Tf will treat files as fixed-form Fortran. That was why compilation was failing. So using CMAKE_Fortran_COMPILE_OBJECT was the proper way to go to make ifort accept f95 files.
So now I am able to use cmake with ifort and f95 files. The CMakeLists.txt section for Intel Fortran is the following:
if (CMAKE_Fortran_COMPILER_ID STREQUAL "Intel")
if(CMAKE_Fortran_COMPILER_VERSION VERSION_LESS "20")
message(FATAL_ERROR "Intel Fortran Compiler 20 or newer required")
endif()
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -warn all")
set (CMAKE_Fortran_FLAGS_RELEASE "-O2")
set (CMAKE_Fortran_FLAGS_RELWITHDEBINFO "-O2 -g")
set (CMAKE_Fortran_FLAGS_DEBUG "-g")
set (CMAKE_Fortran_COMPILE_OBJECT "<CMAKE_Fortran_COMPILER> -o <OBJECT> <DEFINES> <FLAGS> -c -free -Tf <SOURCE>")
endif()
Thank you both for your suggestions.

Disable -Werror for one of CMakeLists.txt

I have the following CMake file:
project(MyLib)
cmake_minimum_required(VERSION 2.8)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "release")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Werror")
set(ROOT_DIR ${CMAKE_SOURCE_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${ROOT_DIR}/bin/${CMAKE_BUILD_TYPE})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ROOT_DIR}/bin/${CMAKE_BUILD_TYPE})
set(MAIN_LIBRARY_NAME "mylib")
add_subdirectory(src)
add_subdirectory(test_app)
add_subdirectory(test_app1) <--- I want to disable -Werror flag for CMakeLists.txt in this folder.
add_subdirectory(test_app2)
How to disable -Werror flag for one of subdirectories? In the each of sub directories I have CMakeLists.txt too.
Turning my comment into an answer
All variables and directory properties are copied to the subdirectory's context at the moment you call add_subdirectory(). Either modify CMAKE_CXX_FLAGS before this call with something like
string(REPLACE " -Werror" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
add_subdirectory(test_app1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
Or use the "old way" were compiler flags could be given with add_definitions() and removed with remove_definitions()
add_definitions(-std=c++11 -Wall -Werror)
...
remove_definitions(-Werror)
add_subdirectory(test_app1)
add_definitions(-Werror)
But you can - in contradiction to my first comment - change flags added add_compile_options() only on target level COMPILE_OPTIONS property and not for complete directories. When the target is created the property is copied as-is from the directory to the target and changing the directory property later won't automatically update the target's property.
If you have a newer CMake version that supports SOURCE_DIR target property you can alternatively go by some crazy generator expression:
add_compile_options(
-std=c++11
-Wall
$<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:SOURCE_DIR>,${CMAKE_SOURCE_DIR}/test_app1>>:-Werror>
)
Reference
Is Cmake set variable recursive?
If you are using CMake v3.24's new CMAKE_COMPILE_WARNING_AS_ERROR variable, which initializes the corresponding target property, you can simply set the variable to FALSE in the CMakeLists.txt file of any subdirectories where you won't want warnings to be errors.
There are two nice things about using this variable:
Cross-platform with less boilerplate: No more explicitly written generator expressions to use the right flag for each compiler.
Allows user-override: Not all users will want to build with warnings as errors. This new feature comes with a --compile-no-warning-as-error command-line flag that users can use to disable any effects of this variable/target-property when set by a dev in a CMakeLists.txt file.
we have a project setup which configured Werror and Wall at the top level as compiler flags. What I ended up doing for a temporary test program which I wanted to skip Werror was:
add_executable(test_program ...)
target_compile_options(test_program PRIVATE -Wno-error)
that ended up generating a compile line like:
g++ ... -Wall -Werror -Wno-error test.cpp -o test
where the -Wno-error cancels out the -Werror, without affecting the CXXFLAGS for the rest of the project.

CMake: different operations with different build type

I want to add some specific flags when I compile in debug mode (GCC/Linux). When I call cmake I want to print all these flags. If I compile in Release mode I don't set these so I don't want to print flags.
Basically I want to print a message only if I build in Debug mode.
In my CMakefile.txt I've following code:
# Setting compiler
if (CMAKE_COMPILER_IS_GNUCXX)
set (USER_DEBUG_FLAGS "-W -Wall -Wextra -Winit-self -Werror")
message(STATUS "Setting extra flags for Linux compiler")
if (CMAKE_BUILD_TYPE MATCHES Debug)
list(APPEND CMAKE_CXX_FLAGS_DEBUG ${USER_DEBUG_FLAGS})
message(STATUS "Debug compiler flags: ${CMAKE_CXX_FLAGS_DEBUG")
endif(CMAKE_BUILD_TYPE MATCHES Debug)
endif(CMAKE_COMPILER_IS_GNUCXX)
If i call cmake with
cmake /path/to/CMakefile.txt/ -DCMAKE_BUILD_TYPE=Debug
I see the first message (so Linux compiler is recognized) but I cannot see the second message.
How can I check if CMAKE_BUILD_TYPE is set to Debug or Release?

Compiling with cmake and include debug information

cmake version 2.8.5
I am trying to compile my project using cmake. However, when i compile I don't think I am including the debug cflags i.e. -ggdb -D_DEBUG. As when I try and debug there is no debub info.
Is there any problem with the CMakeLists.txt files. I have 3 of them
# Mimimum version of cmake required
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
# Name of project
PROJECT(sdp_creator C)
# Check for correct compiler
# Using C compiler GNUCXX for c++ compiler
IF(CMAKE_COMPILER_IS_GNUCC)
MESSAGE(STATUS "=== GCC C COMPILER DETECTED")
SET(CMAKE_C_FLAGS "-m32 -ggdb -D_DEBUG -Wextra -Wall -Wunreachable-code -O0 -D_LARGEFILE64_SOURCE")
ENDIF(CMAKE_COMPILER_IS_GNUCC)
# Using windows compiler i.e. msvc++
IF(WIN32)
MESSAGE(STATUS "=== MSVC COMPILER DETECTED")
ENDIF(WIN32)
# Location of directory where include files are kept
INCLUDE_DIRECTORIES($ENV{HOME}/projects/sdp_creator/src/sdp)
INCLUDE_DIRECTORIES($ENV{HOME}/projects/sdp_creator/src/apr/inc)
# Location of directory where libraries are kept
LINK_DIRECTORIES($ENV{HOME}/projects/sdp_creator/src/apr/lib)
# Add subdirectories
ADD_SUBDIRECTORY(driver)
ADD_SUBDIRECTORY(sdp)
building shared library:
# Create a shared library called libsdp from sdp.c
# NOTE: static is the default
# NOTE: the lib prefix is automatically added
ADD_LIBRARY(sdp SHARED sdp.c)
Creating executable:
# Add executable called sdp_creator from source file
ADD_EXECUTABLE(sdp_creator main.c)
# Link the sdp library and other libraries with the excutable
#if using windows compiler add additional windows libraries
IF(WIN32)
TARGET_LINK_LIBRARIES(sdp_creator libsdp ws2_32)
MESSAGE(STATUS "=== Linking executable with windows libraries")
ENDIF(WIN32)
# if using gcc compiler
# NOTE: no need to add the -l prefix i.e. -lsdp, no automatically
IF(CMAKE_COMPILER_IS_GNUCC)
TARGET_LINK_LIBRARIES(sdp_creator sdp apr-1)
MESSAGE(STATUS "=== Linking executable with posix libraries")
ENDIF(CMAKE_COMPILER_IS_GNUCC)
Many thanks for any advice,
If you're using the "Unix Makefiles" (or any Makefile-based) generator, set the variable CMAKE_BUILD_TYPE to "Debug"
cmake -DCMAKE_BUILD_TYPE=Debug ../src
That will automatically add the right definitions and flags for your compiler. You should not have to add any flags yourself.
With multi-configuration generators, (like Visual Studio and Xcode), CMAKE_BUILD_TYPE is ignored, because the choice of whether to build a Debug or Release configuration is left up to the developer at build-time, and is not known at CMake configure time.
You can check the exact steps used in make by setting VERBOSE=1. That will tell you if the flags were included or not.
cmake project_dir
make VERBOSE=1
You can also check the CMakeCache.txt to see what value is assigned to CMAKE_C_FLAGS variable.
you can use the CMAKE_C_FLAGS and CMAKE_CXX_FLAGS flags with -g0/1/2 (debug information flag for the compiler. -g2 is the highest information):
cmake ... -DCMAKE_C_FLAGS="-g2" -DCMAKE_CXX_FLAGS="-g2" ...
Another option, if unix Makefiles are used to build the project, is to set CMAKE_BUILD_TYPE in CMakeLists.txt file directly:
set(CMAKE_BUILD_TYPE Debug)
You can find more in
$ man cmakevars
Look for CMAKE_BUILD_TYPE