I cloned the SDL_image library and wish to build it using a simple add_subdirectory(...) command. My current directory structure is as follows.
├───lib
│ ├───sdl_image
| ├─── ...
├───build
I have a CMakeLists.txt which is as follows.
cmake_minimum_required(VERSION 3.13)
project(test)
add_subdirectory(lib/sdl_image)
Upon execution (For my environment, cmake . -G "MinGW Makefiles"), I get the following error.
CMake Error at lib/sdl_image/CMakeLists.txt:18 (message):
Prevented in-tree built. Please create a build directory outside of the
SDL_image source code and call cmake from there
In an attempt to fix this, I modified my CMakeLists.txt add_subdirectory(...) command as follows. If I understand correctly, this should specify the output directory to build/sdl_image, outside of the SDL_image source code.
...
add_subdirectory(lib/sdl_image build/sdl_image)
However, I still get the same error. The line that is giving me the error under lib/sdl_image/CMakeLists.txt is as follows.
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR ...)
endif()
I don't understand why this condition is getting triggered since I've specified the source_dir and binary_dir (parameters in add_subdirectory(...)) as very different paths. I also tried add_subdirectory(lib/sdl_image ../../build/sdl_image) in case it was treated as relative to the source_dir. This is still not working.
Any help is appreciated. Thanks.
This is about building in sources (calling cmake in your sources), not a path problem where to put sdl_image.
You probably call cmake from within your source directory which is considered a bad practice (same thing when using autotools, or any other build generator).
So you should have some kind of build tree like:
MyProjectWorkspace
|
\_ sources (tree in your case)
\_ build
and invoke cake with cmake ../build from the build directory.
The reason is that when building in sources, you somehow "pollute" your sources. Very likely you will need to add some .gitignore (if using git) and take special care not to commit thing that are built.
Moreover, when generating code, the generated code will appear in the source tree leading to some confusions at some point (you edit the generated file and see it deleted later).
It is also handy: to completely clear a build, you only need to remove the content of the build directory (would be much harder within the sources)
Last but not least, this also ease the packager's job as usually, the use off source builds.
Related
cmake_minimum_required(VERSION 3.5.1 FATAL_ERROR)
project(WINDOW CXX)
set(WINDOW_SRCS window.cpp)
add_executable(Window ${WINDOW_SRCS})
set(CMAKE_CXX_STANDARD 14)
find_library(OPENGL_LIB
NAMES lGLEW lglfw3 lGL lrt lm ldl lXrandr lXinerama lXxf86vm lXext lXcursor lXrender lXfixes lX11 lpthread lxcb lXau lXdmcp lXi lSOIL lassimp
PATHS /usr/lib /usr/local/lib
)
if(OPENGL_LIB)
target_link_library(Window ${OPENGL_LIB})
endif()
I am trying to write a CMakeList.txt file. I get an error in the generated Makefile
makefile:1: *** missing separator. Stop.
I've added tabs in the beginning of each line. I can't figure out where is wrong
The problem is that you haven't cleaned CMake generated files from the previous CMake configuration run.
Please remove the CMakeCache.txt file and Makefile and the directory CMakeFiles and if they exists the files cmake_install.cmake and CTestTestfile.cmake.
Now you can rerun the CMake configuration via cmake . again.
Then execute make and it should be ok.
In the answer I haven't attempted to improve your CMakeLists.txt, but just to make the issue you are encountering to go away.
Otherwise, as suggested by #roalz, you could use the find_package() to find OpenGL.
Another "improvement" could be to use out-of-source builds. In this way all the build results will be contained in one directory with no interference with the source tree. In this case, to start from a clean state and rerun the CMake configuration, you will only need to remove that build directory, and not all the single files created around. This is particularly useful for projects that have nested source directories (more than one level).
I am quite new to cmake with a makefile background.
I like to use things like include(cmake_utils/header.cmake) to include common snippets of cmake files so that I can include them in my projects but only change them in one once in one place. Where cmake_utils is a git repo.
This is working nicely, but every single CMakeLists.txt I write has to have a cmake_minimum_required.
That is fine, but I may want to change this one day - lets say when one of my common files uses a feature from a newer version of cmake. In that case I don't want to go around changing all the CMakeLists.txt - I just want to change it in one place (ideally).
Here is my current CMakeFile.txt:
cmake_minimum_required(VERSION 3.10.2)
# Include common elements
include(cmake_utils/header.cmake)
include(cmake_utils/cpp_flags.cmake)
# Include path
include_directories(
inc
inc/log4cpp
)
# Include source files by wild card
file(GLOB SOURCES "src/log4cpp/*.cpp")
# Setup output and libs
include(cmake_utils/output_lib_shared.cmake)
include(cmake_utils/common_libs.cmake)
I really want to move the line cmake_minimum_required(VERSION 3.10.2) into my cmake_utils/header.cmake file.
But when I do this I get the following error right at the end of calling cmake:
CMake Error in CMakeLists.txt:
No cmake_minimum_required command is present. A line of code such as
cmake_minimum_required(VERSION 3.10)
should be added at the top of the file. The version specified may be lower
if you wish to support older CMake versions for this project. For more
information run "cmake --help-policy CMP0000".
Is this just a limitation of cmake that I have to live with, or is there a way to archive this?
It's also possible that I am still thinking like a gnu make writer and I have this all horribly wrong :o
Per the documentation cmake_minimum_required: Call the cmake_minimum_required() command at the beginning of the top-level CMakeLists.txt file even before calling the project() command. It is important to establish version and policy settings before invoking other commands whose behavior they may affect.
There is no way of getting around this.
I have a CMake configuration file building two libraries:
a third-party library (here called ThirdPartyLib) containing a real-time OS / board support package from a supplier. It is built outside CMake using the autotools toolchain.
an extended version of the former library (here called ExtendedThirdPartyLib)
Unfortunately, some source code that I need (various tools) are not built in the ordinary build script for (1). Since I don't want to mess with the suppliers build script I want to add another library (2), building the missing files and thus extending the library from the supplier.
I want to able to do something like this in CMakeFiles.txt:
cmake_minimum_required(VERSION 3.2)
project(bsp)
include(ExternalProject)
ExternalProject_Add(
ThirdPartyLib
URL <http://some.url/bsp.tar.bz2
BUILD_COMMAND make -C ../external/ThirdPartyLib/src
)
set_target_properties(ThirdPartyLib PROPERTIES EXCLUDE_FROM_ALL TRUE)
add_library(ExtendedThirdPartyLib
${CMAKE_CURRENT_BINARY_DIR}/some/path/missing_file1.c
${CMAKE_CURRENT_BINARY_DIR}/some/path/missing_file2.c
)
add_dependencies(ExtendedThirdPartyLib ThirdPartyLib)
target_include_directories(ExtendedThirdPartyLib PUBLIC
${CMAKE_CURRENT_BINARY_DIR}/some/path/include
)
target_link_libraries(ExtendedThirdPartyLib ThirdPartyLib)
The problem here is that the path to missing_file1.c and missing_file2.c are not valid when CMake is generating the build files (they are extracted from the tarball from the supplier). CMake exits with an error output saying: "Cannot find source file".
Is there a neat way to make this work? I.e. is it possible to convince CMake that certain non-existant input files will exist when building of the library begins? Or is there any other recommended way to solve this issue?
(I have temporary made local copies of the files I need to build from the suppliers tarball, but that is of course not a good solution. If those files are changed in future versions of the suppliers package and I forget to overwrite my local copies it could be a horrible mess...
Another "solution" would be to create a small makefile outside CMake and use another ExternalProject_Add in the CMakeFiles.txt somehow. But that's not a good solution either, e.g. if compile and linker flags are modified I need to remember to change the makefile too.)
Personally, I dislike the ExternalProject_Add command, because it does way too many things for my taste, but I've digressed.
What if you do something like this, where bar is simulating your ExtendedThirdPartyLib target, since it depends on generated files
cmake_minimum_required(VERSION 3.11)
project(lol C)
set(SOURCES lol.c) # only this file exists
add_library(lol ${SOURCES})
set(FOO_FILES "foo1.c" "foo2.c")
add_custom_command(OUTPUT ${FOO_FILES}
COMMAND ${CMAKE_COMMAND} -E touch ${FOO_FILES}
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "Creating ${FOO_FILES}"
VERBATIM)
add_custom_target(foo DEPENDS ${FOO_FILES})
add_library(bar ${FOO_FILES})
add_dependencies(bar foo)
target_link_libraries(lol bar)
The whole approach hinges on the fact that the method, where produced/generated files are procured, is explicitly defined via the custom command and associated custom target.
You should modify the custom command to extract the required files (e.g. could even call some external script) from the tarball (which might require downloading with curl or something similar).
I understand that by default, Clion creates the binary files for a project loaded in Clion in all the four configurations:
(Debug;Release;MinSizeRel;RelWithDebInfo)
as well as one called: __default__.
I am using a third party cmake module which downloads an external project in a way that add_subdirectory() can be run on it so it would be included in the root project.
add_subdirectory(${downloaded_proj_src_dir} ${downloaded_proj_bin_dir} EXCLUDE_FROM_ALL)
In this setup, if I decide to place the child project outside the binary directory of the root project, I get:
Error:Binary directories outside of CMake build directory are not supported. Most likely this error is caused by an add_subdirectory command with an explicitly specified binary_dir argument.
which is an understandable restriction by CMake.
now if I instead decide to set the binary directory of the downloaded project in a subdirectory of the binary directory of the parent project, ie:
set(downloaded_proj_bin_dir "${CMAKE_BINARY_DIR}/${downloaded_proj}-build")
...
add_subdirectory(${downloaded_proj_src_dir} ${downloaded_proj_bin_dir} EXCLUDE_FROM_ALL)
I will get the file created in the parent binary directory of all the build configurations because ${CMAKE_BINARY_DIR} is different for each configuration. To avoid seeing all these directories listed on the project view sidebar, I have set the CMAKE_CONFIGURATION_TYPES to be Debug. But even then, I get:
Error:Configuration Debug
The current CMakeCache.txt directory /path/Debug/downloaded_proj_bin/CMakeCache.txt is different than the directory /path/__default__/downloaded_proj_bin/CMakeCache.txt where CMakeCache.txt was created. This may result in binaries being created in the wrong place. If you are not sure, reedit the CMakeCache.txt
Clearly something is going on with this __default__ configuration which I don't understand. So the question is, what is the significance of this default configuration and why should there be a conflict here?
P.s. Setting the configuration to __default__ does not solve the problem as I will have a __default__0 configuration created instead and get the same error.
Update: some further observations
My enviornment variables set in IDE don't have any effect on the cmake builds.
Cmake "options" however which presumably will be passed as arguments to cmake do seem to work.
-D CMAKE_CONFIGURATION_TYPES=Debug.
When I specify the command line option, I get
Warning:Manually-specified variables were not used by the project:
CMAKE_CONFIGURATION_TYPES
But it clearly does have the effect of no longer creating the other build configurations. My guess is that this message relates to the __default__ build which is ignoring the argument.
Even in the case of specifying CMAKE_CONFIGURATION_TYPES in the IDE, I still get the additional __default__ build which is apparently unaffected by the CMAKE_CONFIGURATION_TYPES assignment.
Logging: message("Build type: ${CMAKE_BUILD_TYPE} ) does not return any build_type.
Outputting message(and generator: ${CMAKE_GENERATOR} ") returns "Unix-make files" for both, so both are being generated with the same generator.
Taking a diff from the CMakeCache.txt files, I can see that they are identical.
Do you have in DownloadProject.cmake the right setting? for:
set(_DownloadProjectDir "${CMAKE_CURRENT_LIST_DIR}")
I had the same problem trying to set google test(with the help of https://github.com/Crascit/DownloadProject) and my _DownloadProjectDir was setted as "test". Maybe when I moved this cmake file in my project Clion changed that automatically.
So, it turns out that you can sort this out quite easily by adding the following line above line 145 in DownloadProject.cmake:
file(REMOVE "${DL_ARGS_DOWNLOAD_DIR}/CMakeCache.txt")
This seems to be because CLion copies the default across to the other configurations and doesn't clear the cache. This is a problem only because DownloadProject creates a project within the project (I think...). Anyway, deleting this file before configuring the CMakeLists.txt by-passes this issue. I'll submit a pull request to the DownloadProject repository as this doesn't seem to have any adverse effects when not using CLion.
I am getting the following error from CMakeSetup on our source tree:
CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
Missing variable is:
CMAKE_FIND_LIBRARY_PREFIXES
Deleting the cache doesn't help, so something in one of the CMakeLists must be the problem. The weird part is, if I copy in a CMakeCache.txt from an old version of the tree, and edit it so that the paths match, CMake will then configure successfully... and, even after deleting that fixed cache, it continues to configure successfully.
Any idea what I should look for?
There are two variables missing from the bad CMakeCache.txt when it's generated: Project_BINARY_DIR and Project_SOURCE_DIR.
Is your Project declared at the top and in your base CMakeLists.txt file or at the very least this has to be declared before it is needed, of which at the top is easiest.
It appears this is a bug in cmake. http://www.mail-archive.com/cmake#cmake.org/msg13392.html
i.e.
PROJECT(inkscape)
SET(INKSCAPE_VERSION 0.46+devel)
SET(PROJECT_NAME inkscape)
CMAKE_MINIMUM_REQUIRED(VERSION 2.4.6)
SET(CMAKE_INCLUDE_CURRENT_DIR TRUE)
...