How to create a new configuration with CMake - visual-studio

I'm trying to create a NewConfiguration for my project:
set (CMAKE_CONFIGURATION_TYPES "Release;RelWithDebInfo;Debug;NewConfiguration" CACHE STRING "Configurations" FORCE)
But when I run CMake, I have multiple errors:
CMake Error: Error required internal CMake variable not set, cmake may be not be
built correctly.
Missing variable is:
CMAKE_SHARED_LINKER_FLAGS_NEWCONFIGURATION
CMake Error: Error required internal CMake variable not set, cmake may be not be
built correctly.
Missing variable is:
CMAKE_CXX_FLAGS_NEWCONFIGURATION
I think I'm missing something...
I also followed CMake FAQ:
if(CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CONFIGURATION_TYPES Release RelWithDebInfo Debug NewConfiguration)
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
"Reset the configurations to what we need"
FORCE)
endif()
But same errors...
EDIT:
If I do:
SET( CMAKE_CXX_FLAGS_PLAYERVIEWER "-Wall -Wabi" CACHE STRING "Flags used by the C++ compiler during maintainer builds." FORCE )
SET( CMAKE_C_FLAGS_PLAYERVIEWER "-Wall -pedantic" CACHE STRING "Flags used by the C compiler during maintainer builds." FORCE )
SET( CMAKE_EXE_LINKER_FLAGS_PLAYERVIEWER "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING "Flags used for linking binaries during maintainer builds." FORCE )
SET( CMAKE_SHARED_LINKER_FLAGS_PLAYERVIEWER "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING "Flags used by the shared libraries linker during maintainer builds." FORCE )
set (CMAKE_CONFIGURATION_TYPES "Release;RelWithDebInfo;Debug;PlayerViewer" CACHE STRING "Configurations" FORCE)
It creates the new configuration, but I can not compile. I think flags are not correct. I am using Visual Studio 2008.
Thank you :)

I've just created 6 or 7 new configurations for VS2008 with cmake 2.8.4 (now it is days or even hours from 2.8.5 release) for simple hello world project.
The reason why your attemps failed what flags are inccorect e.g. they must be /MDd no -MDd
You notation will work for GCC based compilers, not for VS.
What I recommend you is to get closest flags set and modify it then
set(CMAKE_CXX_FLAGS_FOO ${CMAKE_CXX_FLAGS_DEBUG})
# .. modifiy it - add or remove flags
also i noticed that cmake sometimes does not actually write to .sln or it is not always reloaded (well, I am running win7 on VirualBox maybe it is source of issues).
what i did is the following -
file(GLOB WILL_REMOVE "${CMAKE_CURRENT_BINARY_DIR}/*.vcproj")
execute_process(COMMAND ${CMAKE_COMMAND} -E remove -f ${WILL_REMOVE})
file(GLOB WILL_REMOVE "${CMAKE_CURRENT_BINARY_DIR}/*.sln")
execute_process(COMMAND ${CMAKE_COMMAND} -E remove -f ${WILL_REMOVE})
file(GLOB WILL_REMOVE "${CMAKE_CURRENT_BINARY_DIR}/*.user")
execute_process(COMMAND ${CMAKE_COMMAND} -E remove -f ${WILL_REMOVE})
at least it reloads files :)
however, sometimes i need to run cmake 2 or 3 times to see new configuration at visual studio (can be virtual box, cmake or visual studio bug - have no idea about it).
But, anyway, after 2 or 3
cmake ..
It WORKS!!!!

Despite the CMake FAQ, looks like there is something still a bit unimplemented for this feature request. There is even an open issue for it:
http://www.cmake.org/Bug/view.php?id=5811
Monitor that bug in the CMake bug tracker to be notified as things are updated.

Related

missing .lib file when creating shared library with cmake and visual studio 2019 generator

I have created a personnal C++ library and I try to use it in an other program. To create and compile my library, I use the commands
cmake -G "Visual Studio 16 2019" -A x64 ..
cmake --build . --config Release --target INSTALL
I have no problem with te compilation and the installation, but in the Target-release.cmake install look like this :
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "containers" for configuration "Release"
set_property(TARGET containers APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(containers PROPERTIES
IMPORTED_IMPLIB_RELEASE "C:/Program Files (x86)/containers/lib/containers.lib"
IMPORTED_LOCATION_RELEASE "C:/Program Files (x86)/containers/bin/containers.dll"
)
list(APPEND _IMPORT_CHECK_TARGETS containers )
list(APPEND _IMPORT_CHECK_FILES_FOR_containers "C:/Program Files (x86)/containers/lib/containers.lib" "C:/Program Files (x86)/containers/bin/containers.dll" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
Nothing abnormal, as far as I can see. My problem is : I have no file C:/Program Files (x86)/containers/lib/containers.lib generated during the compilation and the installation. So every time I try to use a find package, I have an error. (It's only with visual studio generator, it works with mingw). Here is my CMakeLists.txt :
cmake_minimum_required(VERSION 3.1)
set(VERSION 1.0.0)
project (containers
VERSION ${VERSION}
DESCRIPTION "Library adding some features to containers of the stl."
LANGUAGES CXX)
option(BUILD_TESTING "Build test programs" OFF)
include(CTest)
# Set the possible values of build type for cmake-gui
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build.")
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
message( STATUS "Sources path : ${PROJECT_SOURCE_DIR}")
message( STATUS "Binary path : ${PROJECT_BINARY_DIR}")
message( STATUS "install path : ${CMAKE_INSTALL_PREFIX}")
message( STATUS "Version : ${PROJECT_VERSION}")
message( STATUS "Version : ${PROJECT_VERSION}")
message( STATUS "Compiler : ${CMAKE_CXX_COMPILER_ID}")
set(SOURCES ${PROJECT_SOURCE_DIR}/src/containers.cpp)
set(HEADERS ${PROJECT_SOURCE_DIR}/include/containers/containers_check.h
${PROJECT_SOURCE_DIR}/include/containers/containers.h
${PROJECT_SOURCE_DIR}/include/containers/append.h
${PROJECT_SOURCE_DIR}/include/containers/contains.h
${PROJECT_SOURCE_DIR}/include/containers/remove.h
${PROJECT_SOURCE_DIR}/include/containers/print.h
)
add_library(containers SHARED ${SOURCES} ${HEADERS})
#add_library(containers INTERFACE)
target_compile_features(containers PRIVATE cxx_std_17)
set_target_properties(containers
PROPERTIES
MSVC_RUNTIME_LIBRARY "MultiThreadedDLL"
CXX_STANDARD_REQUIRED YES
CXX_EXTENSIONS OFF)
target_include_directories(containers
PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
target_compile_options(containers PRIVATE
# g++
#$<$<CXX_COMPILER_ID:GNU>:$<BUILD_INTERFACE:-Wall>>
#$<$<CXX_COMPILER_ID:GNU>:$<BUILD_INTERFACE:-Wextra>>
#$<$<CXX_COMPILER_ID:GNU>:$<BUILD_INTERFACE:-pedantic>>
#$<$<CXX_COMPILER_ID:GNU>:$<BUILD_INTERFACE:-Werror>>
#$<$<CXX_COMPILER_ID:GNU>:-Wno-reorder>
## Clang
#$<$<CXX_COMPILER_ID:Clang>:$<BUILD_INTERFACE:-Wall>>
##TODO
## MSVC
#$<$<CXX_COMPILER_ID:MSVC>:$<BUILD_INTERFACE:/W4>>
#$<$<CXX_COMPILER_ID:MSVC>:$<BUILD_INTERFACE:/WX>>
)
install(TARGETS containers
EXPORT containersTarget
ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/ COMPONENT Development
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/ COMPONENT Library NAMELINK_COMPONENT Development
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin/ COMPONENT Runtimes
)
install(FILES ${HEADERS}
DESTINATION ${CMAKE_INSTALL_PREFIX}/include/containers/
COMPONENT headers)
include(CMakePackageConfigHelpers)
# For moteur_de_calculConfig.cmake
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include CACHE PATH "install path for include files")
set(LIBRARY_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/lib CACHE PATH "install path for libraries")
#------------------------------------------------------------------------------
# Configure <export_config_name>ConfigVersion.cmake common to build and install tree
set(config_version_file ${PROJECT_BINARY_DIR}/containersConfigVersion.cmake)
write_basic_package_version_file(
${config_version_file}
VERSION "${CMAKE_PROJECT_VERSION}"
COMPATIBILITY ExactVersion
)
#------------------------------------------------------------------------------
# Export '<export_config_name>Target.cmake' for a build tree
export(TARGETS
containers
FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Target.cmake"
)
#------------------------------------------------------------------------------
# Configure '<export_config_name>Config.cmake' for a build tree
set(build_config ${CMAKE_BINARY_DIR}/containersConfig.cmake)
configure_package_config_file(
"containersConfig.cmake.in"
${build_config}
INSTALL_DESTINATION "${PROJECT_BINARY_DIR}"
PATH_VARS INCLUDE_INSTALL_DIR LIBRARY_INSTALL_DIR VERSION
)
#------------------------------------------------------------------------------
# Export '<export_config_name>Target.cmake' for an install tree
install(EXPORT
containersTarget
DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/${PROJECT_NAME}"
)
#------------------------------------------------------------------------------
# Configure '<export_config_name>Config.cmake' for a install tree
set(install_config ${PROJECT_BINARY_DIR}/CMakeFiles/containersConfig.cmake)
configure_package_config_file(
containersConfig.cmake.in
${install_config}
INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/${PROJECT_NAME}"
PATH_VARS INCLUDE_INSTALL_DIR LIBRARY_INSTALL_DIR VERSION
)
# Install config files
install(
FILES ${config_version_file} ${install_config}
DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/${PROJECT_NAME}"
)
# test
if(BUILD_TESTING)
add_subdirectory(test)
endif()
# uninstall target
# use : make uninstall
if(NOT TARGET uninstall)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE #ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()
My cmake version :
cmake version 3.18.0
What is missing in my CMakeLists.txt for generate the container.lib file ?
Faced the same problem, I found the solution here: for Visual Studio to export symbols in a .lib file besides the .dll library, you need to set this in your CMake (version>= 3.4) script:
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
Note that the .lib file created this way is a small size file and is not a static library.
CMake manual
I'd like to add to the accepted answer here, for others who might find it: although CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS will solve the problem, it could well be a sticking plaster masking a deeper issue going on with your code.
I'm not an expert on the Microsoft compilers, but I do know that if you build a shared library with MSVC, the .lib file should still be produced. However, rather than containing all of your compiled code as it would for a static library, it basically provides the compiler with information about the exported symbols in your shared library. This means that the compiler can automatically link any other targets to your shared library, without you needing to manually load the library from your code using the Windows API functions. If you link an executable to a shared library this way, the Microsoft C runtime will basically call LoadLibrary() for you automatically when your application starts. Useful, huh?
If the compiler does not produce a .lib alongside your shared library, this basically means that there are no exported symbols in the shared library. This is why CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS solves the problem - it forces all the symbols to be exported anyway, thereby causing the compiler to generate the .lib file detailing these exports. However, as you may be able to work out, this is very much the nuclear option. There's probably a lot of stuff in your shared library that really doesn't need to be visible from the outside! So the pertinent question becomes: why is nothing being exported from my library?
In the linked answer referred to previously, underneath all the CMake technicals, the issue was that the OP was not properly marking their symbols for export. It turns out that this was my issue too, but in a more round-about way: I had decided that for my particular library, which could previously be built in shared or static configurations, I now wanted to force it only to be built in a shared configuration. Because of this, I had removed a particular preprocessor definition from my project in CMake which specified whether the build mode was shared or static; this meant that all of the export annotations on my functions compiled down to nothing (as they should do under a static configuration where they are not needed). The upshot was that I accidentally ended up building the shared library with no exported symbols whatsoever, and MSVC just said "Well I guess there's no point building a .lib then", and didn't produce one. This caused the build issues stating that the .lib could not be found on disk.
When I encountered the answer above, I was suspicious as I wondered why I'd not had to set this value before, despite having used CMake to build Windows shared library projects for years. The correct solution in my case was not to switch CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS on - it was actually to remove the C++ preprocessor condition that checked for my "this is a shared build" preprocessor definition. This re-enabled all of the export annotations on my functions, and everything built as it should.
Before you use CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS, do check that there isn't some subtle bug in your scripts that is preventing your symbols from being exported!

Switch between different build settings

Sorry for the vague title, I'm not sure how to phrase this correctly. I would like to write a cmake script that allows to build a target with different settings for bit width (forced 32 bit, forced 64 bit or native bit width) and static linking. I figured out how to set up the build under each condition and so far I'm using cmake options to switch between different setups.
My problem is that changing one of these build options with ccmake or on the command line also requires to look for new library paths. Since these paths are cached, I currently have to delete the cache when changing bit width. This way users also loose all other settings for options that are independent of bit width and static linking.
Is there a common way to handle this?
Use different build directories for different settings:
cmake -H. -B_builds/arch64 -DCMAKE_CXX_FLAGS=-m64
cmake -H. -B_builds/arch32 -DCMAKE_CXX_FLAGS=-m32
cmake -H. -B_builds/shared -DBUILD_SHARED_LIBS=ON
cmake -H. -B_builds/static -DBUILD_SHARED_LIBS=OFF
cmake -H. -B_builds/debug -DCMAKE_BUILD_TYPE=Debug
cmake -H. -B_builds/release -DCMAKE_BUILD_TYPE=Release
Exceptions
Note that in each case there may be exceptions, like:
add_library(foo STATIC ${FOO_SOURCES}) # BUILD_SHARED_LIBS will be ignored
or for Visual Studio and Xcode Debug/Release will be:
cmake -H. -B_builds/xcode -GXcode
cmake --build _builds/xcode --config Debug # build Debug
cmake --build _builds/xcode --config Release # build Release
instead of xcode-debug and xcode-release
Related
CMAKE_BUILD_TYPE not being used in CMakeLists.txt

CMake to generate a MSVC CUDA project that targets newer devices

My PC has a GTX 580 (compute capability 2.0).
I want to compile a CUDA source that uses dynamic parallelism, a feature introduced in compute capability 3.5.
I know I will not be able to run the program on my GPU, however, it should be possible to compile this code on my machine. I'm assuming this because I can compile with no problems the CUDA samples that use 3.5 capability. These samples come with Visual Studio projects that were "manually generated" (I guess).
I believe my problem is with CMake. I'm using CMake to generate a Visual Studio 2012 project.
My first CMakeLists.txt looked like this:
PROJECT(sample-cuda-tests)
FIND_PACKAGE(CUDA REQUIRED)
INCLUDE_DIRECTORIES(${CUDA_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
FILE(GLOB_RECURSE includes ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h )
FILE(GLOB_RECURSE sources ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cc ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cu )
CUDA_ADD_EXECUTABLE(sample-cuda-tests ${includes} ${sources})
TARGET_LINK_LIBRARIES(sample-cuda-tests ${CUDA_LIBRARIES})
Then, when compiling with the generated Visual Studio 2012 project, I got a warning followed by an error:
warning : The 'compute_10' and 'sm_10' architectures are deprecated, and may be removed in a future release.
error : calling a __global__ function from a __global__ function is only allowed on the compute_35 architecture or above
What was expected. Then I added
list(APPEND CUDA_NVCC_FLAGS -gencode arch=compute_35,code=sm_35)
to the CMakeLists. The warning disappeared, but I got:
error : kernel launch from __device__ or __global__ functions requires separate compilation mode
Ok. So I added to the CMakeLists:
set(CUDA_SEPARABLE_COMPILATION ON)
...and received this:
fatal error : nvcc supports '--relocatable-device-code=true (-rdc=true)', '--device-c (-dc)', and '--device-link (-dlink)' only when targeting sm_20 or higher
What is weird because I thought I was targeting sm_35 (higher than sm_20).
Later I discovered I can set some options directly in CUDA_ADD_EXECUTABLE command. So I removed the line that was appending values to CUDA_NVCC_FLAGS and changed CUDA_ADD_EXECUTABLE command to:
CUDA_ADD_EXECUTABLE(sample-cuda-tests ${includes} ${sources} OPTIONS -gencode arch=compute_35,code=sm_35)
What I got was:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.0\bin\crt\link.stub : fatal error C1083: Cannot open compiler generated file: 'C:/Users/sms/Desktop/sample-cuda-tests/CMakeFiles/sample-cuda-tests.dir/Debug/sample-cuda-tests_intermediate_link.obj': No such file or directory
No idea where to go now. Appreciate any help.
I'm using CUDA SDK 6.0 on Windows 7.
As of CMake 3.1.0, CMake script misses creating a directory to put the intermediate file in.
Add the following snippet in the FindCUDA.cmake
get_filename_component(output_file_path "${output_file}" PATH)
add_custom_command(
TARGET ${cuda_target}
PRE_LINK
COMMAND ${CMAKE_COMMAND} -E make_directory ${output_file_path}
)
right before
if (do_obj_build_rule)
in function CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS
Turned out to be a bug on FindCUDA.cmake.
When setting CUDA_SEPARABLE_COMPILATION to ON, if .cu files are not in the same folder of CMakeLists.txt, intermediate linkage objects are generated in the wrong folder, causing a compilation error that, on Visual Studio, looks like this:
Cannot open compiler generated file: 'project_path/CMakeFiles/project_name/Debug/project_name_intermediate_link.obj': No such file or directory.
I've opened an issue in CMake bug tracker:
http://public.kitware.com/Bug/view.php?id=15016
(the bug is better described there)

How to specify new GCC path for CMake

My OS is centos which has a default gcc in path /usr/bin/gcc. But it is old, I need a new version of gcc. So I install a new version in a new path /usr/local/bin/gcc.
But when I run cmake, it still uses the old version gcc path(/usr/bin/gcc) . How can I specify the gcc to new path(/usr/local/bin/gcc).
I have tried to overwrite /usr/bin/gcc with /usr/local/bin/gcc, but it not work.
Do not overwrite CMAKE_C_COMPILER, but export CC (and CXX) before calling cmake:
export CC=/usr/local/bin/gcc
export CXX=/usr/local/bin/g++
cmake /path/to/your/project
make
The export only needs to be done once, the first time you configure the project, then those values will be read from the CMake cache.
UPDATE: longer explanation on why not overriding CMAKE_C(XX)_COMPILER after Jake's comment
I recommend against overriding the CMAKE_C(XX)_COMPILER value for two main reasons: because it won't play well with CMake's cache and because it breaks compiler checks and tooling detection.
When using the set command, you have three options:
without cache, to create a normal variable
with cache, to create a cached variable
force cache, to always force the cache value when configuring
Let's see what happens for the three possible calls to set:
Without cache
set(CMAKE_C_COMPILER /usr/bin/clang)
set(CMAKE_CXX_COMPILER /usr/bin/clang++)
When doing this, you create a "normal" variable CMAKE_C(XX)_COMPILER that hides the cache variable of the same name. That means your compiler is now hard-coded in your build script and you cannot give it a custom value. This will be a problem if you have multiple build environments with different compilers. You could just update your script each time you want to use a different compiler, but that removes the value of using CMake in the first place.
Ok, then, let's update the cache...
With cache
set(CMAKE_C_COMPILER /usr/bin/clang CACHE PATH "")
set(CMAKE_CXX_COMPILER /usr/bin/clang++ CACHE PATH "")
This version will just "not work". The CMAKE_C(XX)_COMPILER variable is already in the cache, so it won't get updated unless you force it.
Ah... let's use the force, then...
Force cache
set(CMAKE_C_COMPILER /usr/bin/clang CACHE PATH "" FORCE)
set(CMAKE_CXX_COMPILER /usr/bin/clang++ CACHE PATH "" FORCE)
This is almost the same as the "normal" variable version, the only difference is your value will be set in the cache, so users can see it. But any change will be overwritten by the set command.
Breaking compiler checks and tooling
Early in the configuration process, CMake performs checks on the compiler: Does it work? Is it able to produce executables? etc. It also uses the compiler to detect related tools, like ar and ranlib. When you override the compiler value in a script, it's "too late", all checks and detections are already done.
For instance, on my machine with gcc as default compiler, when using the set command to /usr/bin/clang, ar is set to /usr/bin/gcc-ar-7. When using an export before running CMake it is set to /usr/lib/llvm-3.8/bin/llvm-ar.
This question is quite old but still turns up on Google Search. The accepted question wasn't working for me anymore and seems to be aged. The latest information about cmake is written in the cmake FAQ.
There are various ways to change the path of your compiler. One way would be
Set the appropriate CMAKE_FOO_COMPILER variable(s) to a valid compiler
name or full path on the command-line using cmake -D. For example:
cmake -G "Your Generator" -D CMAKE_C_COMPILER=gcc-4.2 -D CMAKE_CXX_COMPILER=g++-4.2 path/to/your/source
instead of gcc-4.2 you can write the path/to/your/compiler like this
cmake -D CMAKE_C_COMPILER=/path/to/gcc/bin/gcc -D CMAKE_CXX_COMPILER=/path/to/gcc/bin/g++ .
Set CMAKE_C_COMPILER to your new path.
See here: http://www.cmake.org/Wiki/CMake_Useful_Variables
Change CMAKE_<LANG>_COMPILER path without triggering a reconfigure
I wanted to compile with an alternate compiler, but also pass -D options on the command-line which would get wiped out by setting a different compiler. This happens because it triggers a re-configure. The trick is to disable the compiler detection with NONE, set the paths with FORCE, then enable_language.
project( sample_project NONE )
set( COMPILER_BIN /opt/compiler/bin )
set( CMAKE_C_COMPILER ${COMPILER_BIN}/clang CACHE PATH "clang" FORCE )
set( CMAKE_CXX_COMPILER ${COMPILER_BIN}/clang++ CACHE PATH "clang++" FORCE )
enable_language( C CXX )
Use a Toolchain file
The more sensible choice is to create a toolchain file.
set( CMAKE_SYSTEM_NAME Darwin )
set( COMPILER_BIN /opt/compiler/bin )
set( CMAKE_C_COMPILER ${COMPILER_BIN}/clang CACHE PATH "clang" )
set( CMAKE_CXX_COMPILER ${COMPILER_BIN}/clang++ CACHE PATH "clang++" )
Then you invoke Cmake with an additional flag
cmake -D CMAKE_TOOLCHAIN_FILE=/path/to/toolchain_file.cmake ...
Export should be specific about which version of GCC/G++ to use, because if user had multiple compiler version, it would not compile successfully.
export CC=path_of_gcc/gcc-version
export CXX=path_of_g++/g++-version
cmake path_of_project_contain_CMakeList.txt
make
In case project use C++11 this can be handled by using -std=C++-11 flag in CMakeList.txt
An alternative solution is to configure your project through cmake-gui, starting from a clean build directory. Among the options you have available at the beginning, there's the possibility to choose the exact path to the compilers
This not only works with cmake, but also with ./configure and make:
./configure CC=/usr/local/bin/gcc CXX=/usr/local/bin/g++
Which is resulting in:
checking for gcc... /usr/local/bin/gcc
checking whether the C compiler works... yes

cmake & gcc compiles every file every time

I'm a learning c++ developer writing a game initially on the Mac platform using XCode, but now moving to cross platform by leveraging CMake. So far I can get it compiled on my ickle linux netbook and I'm putting together a dev environment on this machine for on the go coding. However I'm finding that gcc recompiles every file whenever I make a change. Clearly I need some additional configuration to the CMakeLists.txt . My current one is very simple. Like so;
cmake_minimum_required (VERSION 2.8)
set (source
Creature.cpp
DisplayManager.cpp
Engine.cpp
EngineState.cpp
Entity.cpp
GameWorld.cpp
GfxSFML.cpp
Item.cpp
Map.cpp
Position.cpp
Projectile.cpp
ScreenTile.cpp
SquadAI.cpp
Terrain.cpp
UIButton.cpp
UICharPanel.cpp
UIView.cpp
Utility.cpp
Weapon.cpp
fov.cpp
main.cpp
)
find_package (OpenAL)
find_package (OpenGL)
find_package (SFML)
set(CMAKE_CXX_FLAGS "-g -Wall -pg")
add_executable (tractionedge ${source})
target_link_libraries(tractionedge ${SFML_LIBRARY} ${OPENGL_LIBRARY} ${OPENAL_LIBRARY})
I've concentrated so far on C++ as a language rather than build systems by sticking with XCode for everything. My knowledge of Autotools (make?) and Gcc is very limited. How do I have gcc only recompile the changed source?
Are you rerunning cmake every time? If you just modify one source file, you should be able to simply rerun make, and it should rebuild just the one object file before linking. If you rerun cmake, it might mark all of the source files dirty and rebuild everything.
Only rerun cmake if you change the actual list of source files being used, or other major changes like that.
Rebuilding only the modified sources SHOULD be the default behavior. Of course if you change a central header included by nearly all dependent cpp files it'll trigger a nearly complete rebuild. Look at what happens if you only modify one cpp file (adding a comment or alike), if more than that compilation unit is compiling then I propose you to invest more time investigating it eventually giving you my EMail to have a deeper look at the configuration.
Another possibility is that you are compiling under windows and using a 2.8 cmake that has a bug regarding this. Look at a 2.9 version to see if that defect is away then: http://www.mail-archive.com/cmake#cmake.org/msg24876.html
I would rewrite your CMakeLists.txt using glob (maybe move the files in a "src" directory if you have other *.cpp files around) and give your project a name (this sets some important variables):
cmake_minimum_required (VERSION 2.8)
project(TRACTION)
file (GLOB TRACTION_SOURCES *.cpp)
find_package (OpenAL)
find_package (OpenGL)
find_package (SFML)
set(CMAKE_CXX_FLAGS "-g -Wall -pg")
add_executable (tractionedge ${TRACTION_SOURCES})
target_link_libraries(tractionedge ${SFML_LIBRARY} ${OPENGL_LIBRARY} ${OPENAL_LIBRARY})
I also experienced unnecessary rebuilds using cmake and visual studio. The problem is related to an inappropriate x64 configuration parameter: Visual Studio 2008 Unnecessary Project Building
A simple solution in many of these cases is to completely wipe the build tree and regenerate it (and I mean something along the lines of rm -rf build && mkdir build && cd build && cmake -G "Unix Makefiles" ../src, not just make clean)

Resources