I could not find any question that was helpful concerning my question, so here it is (or prove me wrong).
First: I do everything under Windows and build only for Visual Studio.
My Situation: I have my main directory which contains a "main" CMakeLists. So here is were to make the cmake call and it does not much itself:
cmake_minimum_required(VERSION 3.13.1)
project (EulerAdventureReinvented)
if (CMAKE_GENERATOR MATCHES Win64)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/Win64/")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/Win64/")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/bin/Win64/")
else()
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/Win32/")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/Win32/")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/bin/Win32/")
endif()
add_subdirectory(source)
But it adds another CMakeLists in the source directory which does the setup for the "main" project. So it contains the add_executable call and I wanna keep it that way. But the problem is that it does write the vcxproj files, CMakeFiles dir into that source directory, but I want them in the root directory or... well just somewhere else.
Final Question: What do I need to set for this? I mean which variable is the one I want to change. I searched and found so many that I came to a point of trial and error and even then did not find my files somewhere else.
EDIT: I changed the title a bit to avoid confusion between build and generated files. I do not want to set the build path, since that is already done by the above code.
In CMake 3.13.2 the following switches are available:
cmake [<options>] -S <path-to-source> -B <path-to-build>
So in the case you described above it would be something like:
cmake -S . -B .\build
Now, there is no variable for setting <path-to-build> but you can get it's information from CMAKE_BINARY_DIR. The variables you are setting control where artifacts wind up but not where project files are created or intermediate files are located.
Related
I am developing a system of build scripts for CMake and have an issue with wanting to have intermediate CMakeLists.txt files appear in the IDE for easier search and edit.
I have a main CMake file that includes a directory that includes several subdirectories for libraries.
CMakeLists.txt
--- SubProjects:
-------CMakeLists.txt
-------ProjectAFolder:
----------CMakeLists.txt
-------ProjectBFolder:
----------CMakeLists.txt
-------ProjectCFolder:
----------CMakeLists.txt
In the SubProjects folder, the CMakeLists.txt is very simple and just includes the subproject folders one after the other:
SET(SUBDIRECTORIES ProjectAFolder
ProjectBFolder
ProjectCFolder )
foreach (subdirectory ${SUBDIRECTORIES})
add_subdirectory(${subdirectory})
endforeach ()
However, when I generate this in XCode or Visual Studio, the IDE does not include the intermediate CMakeLists.txt file anywhere because it does not belong to any individual library or executable target. What is the best way to include this somewhere so it appears in an IDE?
Depends on where you want the file to show up, since it doesn't belong to any target. You can simply add it to any existing target (just as you do with source files) or you can create a new custom target.
add_library(AnyExistingTarget <other source files> SubProjects/CMakeLists.txt)
Or create a custom target:
add_custom_target(MyIntermediateCMakeFiles SubProjects/CMakeLists.txt)
For Visual Studio, you could also use the built-in support for cmake. It will display the source tree in the IDE without any extra work.
I would like to generate a module definition file based on all symbols available in object files in dynamic fashion (think of GTKMM's gendef).
For this, I would like to add_custom_command for PRE_LINK step of a target. However, it looks like there is no easy way to get path to all object files with CMake that would work for plain makefiles as well as for multi-configuration generators like Visual Studio.
Right now, I have the following
add_custom_command(TARGET tgt PRE_LINK
COMMAND gendef ${CMAKE_CURRENT_BINARY_DIR}/tgt.def $<TARGET_FILE_NAME:tgt> ${CMAKE_CURRENT_BINARY_DIR}/$<$<BOOL:${CMAKE_BUILD_TYPE}>:${CMAKE_FILES_DIRECTORY}>/tgt.dir/${CMAKE_CFG_INTDIR}/*.obj
)
However this is quite awkward and bulky as I have to use generator expression in my opinion. Is there a better way to achieve this effect, i.e. call a certain external program for each build configuration?
Is it a CMake bug (feature?) that for plain makefiles, all object files go to CMakeFiles/tgt.dir folder while for multiconfiguration generators all goes to a sibling of CMakeFiles, i.e. tgt.dir/$<CONFIG>? Did I miss some simple variable that would point me to the right place directly?
Turning my comment into an answer
Makefile projects generated by CMake have a totally different internal structure then solutions/projects generated for Visual Studio. I think this is neither a bug nor a feature, those structures are just optimized for their usecases.
And as far as I know there is no easy CMake internal way to get the list of object files or the path to the intermediate files directory with e.g. reading a target property.
So I have taken your code example and have done some testing for alternatives with CMake 3.3.2 using Visual Studio 14 2015 and NMake Makefiles generators.
Alternatives
One related discussion on the CMake mailing list named "CMake: Is there an elegant way to get list of object files participating into a library?" does suggest using an intermediate static library:
add_library(tgtlib STATIC tgt.c)
add_custom_command(
OUTPUT tgt.def
COMMAND gendef tgt.def $<TARGET_FILE_NAME:tgt> $<TARGET_FILE:tgtLib>
)
file(WRITE dummy.c "")
add_library(tgt SHARED dummy.c tgt.def)
target_link_libraries(tgt tgtlib)
You could add build environment specific elements to your PRE_LINK step:
if(CMAKE_CONFIGURATION_TYPES)
set(_obj_files "$(IntermediateOutputPath)*.obj")
else()
set(_obj_files "$?")
endif()
add_custom_command(
TARGET MainProject
PRE_LINK
COMMAND gendef tgt.def $<TARGET_FILE_NAME:tgt> ${_obj_files}
)
References
NMAKE: Filename Macros
When i run my program in MPLAB. ( Project wizard -> PIC16F877A -> Hi Tech Ansi C Compiler -> RUN )
Error [141] C:\Users\WhyWhy\Desktop\test.c; 1.22 can't open include file "16F877A.h": No such file or directory
Where can i find the header file for the 16F877A?
Chip-specific header files should not be explicitly included in HITECH-C, the documentation clearly states that. Instead, you include the compiler header, which will take care of including the chip-specific file for you:
#include <htc.h>
All you need for this to work is to configure correct chip in the project settings. The 16F877A.h file exists in the compiler directory, but including it directly will throw a warning.
C:\Program Files\HI-TECH Software\PICC\9.70\include
In my case , I have installed HITech Compiler In C:\ Program Files.
You have to know, where have you installed the files of the compiler.
This file is from the compiler, so in your case the Hi Tech you can find here:
C:\Program Files\HIāTECH Software\PICC\\include\
Before you have found the file you have to add in the Header Files folder in the Project window on MPLAB.
And in your code you have to include it
#include <16F877A.h>
I have a project where the source files are in source/ and some shader files in data/ (those are not compiled, but instead loaded by the code). I'd like these files to show up in my CMake-generated VS2010 project files so I can edit them comfortably. What's a good way to do this? Ideally, they'd be in a separate project, but anything that works is good.
Thanks!
I can't comment (reputation too low) but is this what you want ?
http://www.cmake.org/pipermail/cmake/2006-May/009291.html
EDIT: if the above link stops working at some time, the idea is to add the files to Visual Studio like an ordinary source file. Since the IDE has no compile tool associated with it, it will be ignored. Quoting the list's discussion:
You could add arbitrary files to a target - as long as VS has no
"automatic" rule to compile them (e.g. .cc, .cpp etc)
I am adding .html files to libraries/executable or using a dummy target e.g:
ADD_EXECUTABLE(dummy dummy.cpp
"${CMAKE_CURRENT_BINARY_DIR}/Doc/index.html")
SOURCE_GROUP command may be useful, too.
and also
I think you have to take care that they are added only to VS IDE
generator builds,
in particular NOT to makefiles.
Thus we are using something like this:
IF (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
ADD_EXECUTABLE( hello ${SOURCES} ${HEADER} ${DOC})
ELSE (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
ADD_EXECUTABLE( hello ${SOURCES} )
ENDIF (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
Credit to Jan Woetzel
I'm generating a VS2010 solution with a few projects (currently 4, will be up to 10-20 in the end). I only want one of them to build; the rest should be disabled. I can do this manually by going into the configuration manager and unchecking the boxes I don't want, but obviously this isn't a good solution.
Is there something I can add to the CMakeLists.txt file for a project that will cause it to do this? Searching through the docs, google and SO yielded nothing.
Update: Here is my root CMakeLists.txt in case that helps:
cmake_minimum_required(VERSION 2.8)
add_definitions(-DCOMPILER_MSVC)
project (PDEngine)
set(LINKER_LANGUAGE CXX)
add_subdirectory (units/platform)
add_subdirectory (units/render_api)
add_subdirectory (units/memory)
add_subdirectory (units/game)
set(custom_exe "${CMAKE_CURRENT_BINARY_DIR}/units/Platform/Debug/Platform.lib2")
add_custom_command(OUTPUT ${custom_exe}
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/local/msvc/bam.bat -j $ENV{NUMBER_OF_PROCESSORS}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/local/msvc/bam.bat
)
#add_custom_command(OUTPUT ${custom_exe_clean}
#COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/local/msvc/bam.bat -c
#DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/local/msvc/bam.bat
#)
add_custom_target(bam ALL DEPENDS ${custom_exe})
#add_custom_target(bamclean ALL DEPENDS ${custom_exe_clean}})
(The bam.bat stuff is based off of the answer I got here: How do I configure CMake to make the VS solution use a specific build commandline? )
And here's the CMakeLists.txt for the "platform" project:
cmake_minimum_required (VERSION 2.8)
project (Platform)
set (COMPILER_MSVC 1)
include_directories(${Platform_SOURCE_DIR}/include)
file(GLOB Project_HEADERS ${Platform_SOURCE_DIR}/include/platform/*.h)
source_group("Headers" FILES ${Project_HEADERS})
add_library(Platform STATIC EXCLUDE_FROM_ALL src/*.cpp ${Project_HEADERS})
So if what you want to do is not build something by default, you can remove it from the "ALL" target (which shows up in Visual Studio as ALL_BUILD). The way you do this is with the target property EXCLUDE_FROM_ALL, or by passing EXCLUDE_FROM_ALL to add_executable and add_library. (Custom targets default to EXCLUDE_FROM_ALL, so there, to do the reverse, you add ALL to the arguments to add_custom_target).
Then, all your targets will show up, but when clicking "build solution", only the ones you want will build. Others can be built by right clicking them and choosing "Build", like the built-in INSTALL project/target.
There is a EXCLUDE_FROM_DEFAULT_BUILD target property for that purpose.
See https://stackoverflow.com/a/14911387/594456.