what happens to the SET of Cmake [duplicate] - cmake

This question already has answers here:
What's the CMake syntax to set and use variables?
(3 answers)
Closed 2 years ago.
here is my code of cmake :
PROJECT (HELLO)
SET(SRC ./main.c)
MESSAGE(STATUS "This is BINARY dir "${HELLO_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir"${HELLO_SOURCE_DIR})
ADD_EXECUTABLE(hello SRC)
if I run, what appears in front of me is that:
-- Configuring done
CMake Error at CMakeLists.txt:5 (ADD_EXECUTABLE):
Cannot find source file:
SRC
Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
.hxx .in .txx
CMake Error: CMake can not determine linker language for target: hello
CMake Error: Cannot determine link language for target "hello".
-- Generating done
if I change my code to
PROJECT (HELLO)
SET(SRC ./main.c)
MESSAGE(STATUS "This is BINARY dir "${HELLO_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir"${HELLO_SOURCE_DIR})
ADD_EXECUTABLE(hello ./main.c)
it just works well.
So, what happens to SET? why didn't it work well?

You need to use:
ADD_EXECUTABLE(hello ${SRC})
Otherwise, cmake just thinks you have a source file named "SRC" leading to that error you see.

Related

How to add a .h file to a flex definition in CMake

So I am trying to use flex in a project with Clion (because I'm on windows), which uses CMake but I cannot compile because my lexer.l file includes token.h
my CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
find_package(FLEX)
FLEX_TARGET(MyScanner lexer.l ${CMAKE_CURRENT_BINARY_DIR}/lex.yy.c)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_executable(lexer token.h ${FLEX_MyScanner_OUTPUTS}
printtoken.c lexan.h lexanl.c )
ERROR:
[ 16%] Building C object CMakeFiles/lexer.dir/lex.yy.c.o
lexan.l:36:10: fatal error: token.h: No such file or directory
compilation terminated.
CMakeFiles/lexer.dir/build.make:74: recipe for target 'CMakeFiles/lexer.dir/lex.yy.c.o' failed
How do I include the token.h?
Problem Solved:
I had to add ${CMAKE_SOURCE_DIR} to the include_directories() call for it to find the header file.

cmake, how to add project to a solution?

I have the jpeglib library, built with cmake and visual studio 2005. And I also have a separate program that uses this library. How can I compile that program so that I can debug both program and library code?
My first attempt was by just including the main program's project into the libjpeg solution, changing include paths and specifying the path to libjpeg .lib. This worked, but when I rerun cmake, I have to redo that. I described it here: https://board.flatassembler.net/topic.php?p=203834#203834
How can I compile those two programs using cmake itself? I tried adding this in the libjpeg CMakeList.txt :
add_executable(_main--ddraw main.cpp)
set_property(TARGET _main--ddraw PROPERTY RUNTIME_OUTPUT_DIRECTORY "c:/_src/_main--ddraw3")
target_link_libraries(_main--ddraw jpeg-static)
But it only resulted in this:
1>CMake Error at CMakeLists.txt:369 (add_executable):
1> Cannot find source file:
1> main.cpp
1> Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
1> .hxx .in .txx
1>CMake Error: CMake can not determine linker language for target: _main--ddraw

CMake Error at CMakeLists.txt (add_library): [duplicate]

This question already has answers here:
Automatically add all files in a folder to a target using CMake?
(5 answers)
Closed 6 years ago.
I wan't to compile an external library:
It works with the complete path of the source like:
add_library(timetool "../src/wnt/foo.cxx"
"../../../../include/foo.h"
It DOESN'T works
add_library(timetool "../src/wnt/*.cxx"
"../../../../include/*.h"
And I get the error message:
CMake Error at CMakeLists.txt:25 (add_library):
Cannot find source file:
../src/*.cxx
Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp .hxx .in .txx
What can I do to solve the Problem?
And that is the solution! No whildcards in function add_library
file(GLOB timetool_SRC "../src/wnt/*.cxx"
"../../../../include/*.h"
add_library(timetool ${timetool_SRC}

CMake: cannot find source file on add_library of sibling library

I have a CMake project with the following directory structure:
CMakeLists.txt
A/CMakeLists.txt
B/CMakeLists.txt
A and B both describe shared libraries, and B depends upon A.
Calling cmake on the entire project gives no problems. Neither does building A, but building B tells me it misses symbols from A. This makes sense, and so I solved that by adding target_link_libraries(B A) to B/CMakeLists.txt.
However, when I call cmake now, I get errors about B/CMakeLists.txt not being able to find source files from A. Apparently, to solve this, I should add target_include_directories(A PUBLIC .) to A/CMakeLists.txt, but that does not work. What am I missing here?
For completion's sake, here's the dumbed-down CMake files:
cmake_minimum_required (VERSION 3.5.1)
project(main C CXX)
add_subdirectory(A)
add_subdirectory(B)
A/CMakeLists.txt
cmake_minimum_required (VERSION 3.5.1)
add_library(A SHARED "")
target_include_directories(A PUBLIC .)
target_sources(A PUBLIC ...)
B/CMakeLists.txt
cmake_minimum_required (VERSION 3.5.1)
add_library(B SHARED "")
target_link_libraries(B A)
target_sources(B PUBLIC ...)
The error I get is the following
CMake Error at B/CMakeLists.txt:3 (add_library):
Cannot find source file:
Access.hpp
Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp .hxx .in .txx
I'm following this tutorial, explaining about target_link_libraries and target_include_directories.
Don't use target_sources(). Add source files to the add_library() command.
Or use target_sources() with PRIVATE.

Using constant folder with cmake

I have a constant MYPROJECT in my ~/.bashrc file:
export MYPROJECT = /home/loom/my_project
I can see the constant is defined in the terminal:
loom#loom$ ls -ld $MYPROJECT
drwxr-xr-x 25 loom loom 4096 Jul 21 22:12 /home/loom/my_project
I tried to use the constant in my CMakeLists.txt:
add_executable(booo src/main.cpp ${MYPROJECT}/foo/trunk/bar/File.h)
However, it produces an error:
CMake Error at CMakeLists.txt:17 (add_executable):
Cannot find source file:
/foo/trunk/bar/File.h
Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
.hxx .in .txx
CMake Error: CMake can not determine linker language for target: booo
CMake Error: Cannot determine link language for target "booo".
It is processed without errors if I have used explicit path without $MYPROJECT:
add_executable(booo src/main.cpp /home/loom/my_project/foo/trunk/bar/File.h)
How to use path defined in .bashrc in cmake?
Instead of
add_executable(booo src/main.cpp ${MYPROJECT}/foo/trunk/bar/File.h)
use
add_executable(booo src/main.cpp $ENV{MYPROJECT}/foo/trunk/bar/File.h)
The CMake documentation states:
Use the syntax $ENV{VAR} to read environment variable VAR. See also
the set() command to set ENV{VAR}.
https://cmake.org/cmake/help/v3.4/variable/ENV.html
Turning my comment into an answer
There are a lot of ways you could do this in CMake. Out of bad experiences with using environment variables directly inside CMake projects (they have to be valid not only during the first call to CMake configuration/generation but also later during all consecutive builds), I would recommend to transfer your constant into a cached CMake variable.
I'm using one of the following ways in my projects:
Injecting MYPROJECT CMake via its -D option, e.g.
cmake -DMYPROJECT:PATH=$MYPROJECT ..
Then CMake would cache this value in its own MYPROJECT internal variable.
When you get values from the "outside" you should think about what to do if no value is provided or it's not a valid directory. Throwing a fatal error and/or retry with a default value?
The following example shows only transformation steps and sanity checks (no default value retry):
if (NOT DEFINED MYPROJECT OR NOT IS_DIRECTORY MYPROJECT)
file(TO_CMAKE_PATH "$ENV{MYPROJECT}" _ENV_MYPROJECT_REL)
get_filename_component(_ENV_MYPROJECT "${_ENV_MYPROJECT_REL}" ABSOLUTE)
if (NOT _ENV_MYPROJECT)
message(FATAL_ERROR "Environment variable MYPROJECT not provided.")
else()
set(MYPROJECT "${_ENV_MYPROJECT}" CACHE INTERNAL "")
endif()
endif()
Using find_path(), which will also cache its result:
find_path(
MYPROJECT_INCLUDE_DIR
NAMES File.h
PATHS ENV MYPROJECT
/home/loom/my_project
PATH_SUFFIXES foo/trunk/bar
)
if (NOT MYPROJECT_INCLUDE_DIR)
...
Or - assuming your external project does not only consists of header files but also libraries like foo.a - following CMake's A Sample Find Module and extending the find_path() code from above by:
find_library(
MYPROJECT_LIBRARY
NAMES foo
PATHS ENV MYPROJECT
PATH_SUFFIXES foo/lib
)
if(MYPROJECT_INCLUDE_DIR AND MYPROJECT_LIBRARY AND NOT TARGET MyProject::MyProject)
add_library(MyProject::MyProject UNKNOWN IMPORTED)
set_target_properties(
MyProject::MyProject
PROPERTIES
IMPORTED_LOCATION "${MYPROJECT_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${MYPROJECT_INCLUDE_DIR}"
)
endif()
Now you can use it directly as any other CMake target with
add_executable(booo src/main.cpp)
target_link_libraries(booo MyProject::MyProject)
More References
What's the CMake syntax to set and use variables?
preferred cmake project structure