Im following the popular cpu emulation series by Dave Poo on Youtube. Im on the second episode where we integarate googletest. Im getting all kind of errors but the most not understandable one is a "Cannot find source file".
This is the CMakeLists file
cmake_minimum_required(VERSION 3.23)
project(ProjectName)
include(FetchContent)
FetchContent_Declare(
googletest
# Specify the commit you depend on and update it regularly.
URL https://github.com/google/googletest/archive/e2239ee6043f73722e7aa812a459f54a28552929.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
# Now simply link against gtest or gtest_main as needed. Eg
add_executable( M6502test main.cpp)
#target_link_libraries(M6502test gtest)
#target_link_libraries(M6502test M6502lib)
I have commented out the link_libaries since they are causing errors aswell.
The structure of the project is 2 folders M6502lib and M6502test. The first one has the actual code in a header file while the latter has a main function. CmakeList file is on the same level as the FOLDERS not the files.
I havent been able to set up googleset for a whole day so other info on the how I should do it would be great as I am getting loads of other errors.
Related
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.
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 have the following cmake setup:
colorizer_root
|
|-------colorizer_lib
|-------colorizer_template_project
The colorizer_root contains the top level CMakeLists.txt which is invoked when running cmake:
colorizer_root CMakeLists.txt
project(colorizer_root)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_BUILD_TYPE Debug)
add_subdirectory(colorizer_lib)
add_subdirectory(colorizer_template_project)
As you can see it contains 2 subdirectories each a project on its own. Basically what the colorizer_lib does is create a shared library named libcolorize.so (no executables here!), which then is to be used by the other project colorizer_template_project (the executable is created in this project). Here are the two CMakeLists.txt files for their respective projects:
colorizer_lib CMakeLists.txt
project(colorizer_lib)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_CXX_FLAGS "--std=gnu++11 ${CMAKE_CXX_FLAGS}")
include_directories(. INCLUDES)
add_library(colorizer SHARED colorizer.cpp)
colorizer_template_project CMakeLists.txt
project(colorizer_template_project)
cmake_minimum_required(VERSION 2.8)
find_library(COLORIZER_LIB colorizer
PATHS ${CMAKE_BINARY_DIR}/colorizer_lib
)
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(${PROJECT_NAME} ${COLORIZER_LIB})
I'm having trouble figuring out how the whole lookup thing works. The problem here is that when I run the top level CMakeLists.txt it goes through both (obviously) but during processing the colorizer_template_project it breaks with a complaint:
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
COLORIZER_LIB
linked by target "colorizer_template_project" in directory /home/USER/Programming/C_Cpp/colorizer/colorizer_template_project
This is an expected behaviour since libcolorizer.so cannot be present at the time of running cmake because it is created after make has been invoked.
How do I tell cmake to first process the first project (including the build step!) and then go to the next one? I know that this works if I add an executable to the project that creates the library and then directly link it to the binary but in this case I want separate projects for the library and the executable that is using it.
PS: I haven't given any details about the sources because they are not important here. It is - I believe - a general question, which is not specific to whether I'm using C, C++ or something similar.
project command doesn't make subprojects independent, so colorizer target is actually accessible for colorizer_template_project, and you can directly link with it:
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(${PROJECT_NAME} colorizer)
I'm brand new to the world of linux, cmake, and software/computers in general (I'm just learning how to work with the command line if that gives you an idea of where I'm at) yet somehow found myself working as a software intern (I'm an EE major). I've been tasked to build a software package using cmake and make and it is not going well. I'm making an effort to understand every single line within the top level CMakeLists.txt file associated with the package and am feeling incredibly incompetent. I've gone through some documentation about cmake in general and although I have a sense of how cmake uses CMakeLists.txt files there are some specifics that require clarification.
1) There are a number of variables that are being used and I would like to find out what their values are. However, not all of the variables within the CMakeLists.txt file are shown in the CMakeCache.txt file. For example, consider the following command shown below
SET(bioreader_common_LIBS
${bioreader_common_LIBS}
QtCore
QtScript
QtScriptTools
QtNetwork
QtGui
QtTest
QtXml
QtDBus
QtSql
mongoclient.a
bsd
ssl
crypto
boost_system
boost_thread
boost_filesystem
boost_program_options
)
Nowhere in the CMakeLists.txt file is the variable bioreader_common_LIBS defined and its not contained in the cache. It seems obvious that it's "value" is simply a list of libraries. Is there a way (maybe through the command line) to return the value of this variable?
2) After a google search about cmake variables I came across a wiki page detailing useful cmake variables (http://www.cmake.org/Wiki/CMake_Useful_Variables). I've been trying to find the value of a lot of these variables but with little luck. For example, one of the "useful variables" is CMAKE_LIBRARY_PATH. Although there is no reference to this variable within the CMakeLists.txt or CMakeCache.txt files, it seems as though it should still exist and have a value and yet I can't find it?
3) One of the biggest issues I've run into after running cmake and make is failing to link against certain libraries. For example, there is a required sql database driver plugin (mysql) which I believe exists as 12 .so files located in usr/lib/mysql/plugin. I realize that I need to modify the CMakeLists.txt file to include these libraries or perhaps add the path somewhere but I'm not sure how to do it. Even if I knew where to add the library I'm not sure how to name the library within the CMakeLists.txt (I thought the name of the driver was "mysql" but apparently that's technically not what you would refer to it as within the CMakeLists.txt file).
The CMakeLists.txt file I'm referring to is shown below. Sorry if this question seems stupid but I'm totally lost and feeling very frustrated.
cmake_minimum_required(VERSION 2.4)
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
endif(COMMAND cmake_policy)
project (bioreader)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/;${CMAKE_MODULE_PATH}")
# Find Qt libraries
INCLUDE(FindQt4) # will find QMake moc includes and libraries for us
INCLUDE(${QT_USE_FILE})
FIND_PACKAGE(Qt4 REQUIRED)
LINK_DIRECTORIES(${QT_LIBRARY_DIR})
# Find MongoDB libraries
FIND_PACKAGE(MongoDB REQUIRED)
# Find Boost libraries
FIND_PACKAGE(Boost REQUIRED)
# Custom dependencies
INCLUDE(AddFileDependencies)
# Qt/Qtopia
include (${QT_USE_FILE})
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtCore/)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtGui/)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtNetwork/)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtScript/)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtScriptTools/)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtTest/)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtXml/)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtDBus/)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtSql/)
# Optimized?
OPTION (OPTIMIZED "Compile in the optimized mode?" ON)
OPTION (ATOM "Optimize for Intel Atom 32-bit?" OFF)
OPTION (PROFILING "Add profiling information to executable?" OFF)
ADD_DEFINITIONS (-Wall -fno-strict-aliasing -Wno-strict-aliasing)
IF(OPTIMIZED)
ADD_DEFINITIONS (-O3)
IF (ATOM)
ADD_DEFINITIONS (-m32 -march=core2 -mtune=pentium -mfpmath=sse)
ENDIF (ATOM)
ELSE(OPTIMIZED)
ADD_DEFINITIONS (-g)
ENDIF(OPTIMIZED)
IF(PROFILING)
ADD_DEFINITIONS (-pg)
ENDIF(PROFILING)
# Ban exceptions? (used only for testing/refactoring)
OPTION (KILL_EXCEPTIONS "Disable support for exceptions?" OFF)
IF (KILL_EXCEPTIONS)
ADD_DEFINITIONS(-fno-exceptions)
ENDIF(KILL_EXCEPTIONS)
# Attempt to compile the code with ALL warnings enabled (ie. "pedantic
# mode")?
OPTION (PEDANTIC_MODE "Compile with all compiler warnings enabled?" ON)
IF (PEDANTIC_MODE)
ADD_DEFINITIONS (-pedantic -Wno-long-long -DUSING_PEDANTIC_MODE)
ENDIF (PEDANTIC_MODE)
# Linear algebra library
OPTION (LAPACK "Use LAPACK linear algebra library" ON)
IF(LAPACK)
MESSAGE(STATUS "Building using LAPACK.")
ADD_DEFINITIONS (-DUSING_LAPACK)
ELSE(LAPACK)
MESSAGE(STATUS "Building WITHOUT using LAPACK.")
ENDIF(LAPACK)
# Package subdirectories. These statements load the CMakeLists.txt files
# from the subordinate directories.
##
add_subdirectory (src/IO)
add_subdirectory (src/Instrument)
add_subdirectory (src/Protocol)
add_subdirectory (src/Script)
add_subdirectory (src/Physical)
add_subdirectory (rc/data)
add_subdirectory (rc/jslib)
add_subdirectory (rc/gfx)
add_subdirectory (rc/svninfo)
# Set up generic includes
include_directories (${bioreader_SOURCE_DIR})
include_directories (${bioreader_SOURCE_DIR}/src)
link_directories (${bioreader_BINARY_DIR})
link_directories (/usr/lib)
##
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
SET (bioreader_common_LIBS
Instrument
rcjslibCore
rcjslibBioScript
rcjslibRobot
rcgfx
rcsvninfo
rcdata
Physical
PhysicalController
PhysicalUnit
Protocol
IO
IOqextserialport
)
SET(bioreader_common_LIBS
${bioreader_common_LIBS}
QtCore
QtScript
QtScriptTools
QtNetwork
QtGui
QtTest
QtXml
QtDBus
QtSql
mongoclient.a
bsd
ssl
crypto
boost_system
boost_thread
boost_filesystem
boost_program_options
)
IF(LAPACK)
SET (bioreader_common_LIBS
${bioreader_common_LIBS}
lapack
blas
gfortran)
ENDIF(LAPACK)
SET (bioreader_reader_LIBS
InstrumentBuilderReader
InstrumentBuilderUnitTest
ProtocolTest
InstrumentTest
PhysicalControllerTest
PhysicalUnitTest
InstrumentBioTest
InstrumentBio
Script
PhysicalPump
PhysicalElevator
PhysicalMotor
PhysicalRobot
${bioreader_common_LIBS}
)
##
## BIOSCALE_QUICKAPP APPNAME SOURCES src1.cpp src2.cpp LIBS
##
MACRO(BIOSCALE_QUICKAPP APPNAME)
SET(__MODE "SOURCES") # default
FOREACH(ARG ${ARGN})
IF( ${ARG} STREQUAL "SOURCES" )
SET(__MODE "SOURCES")
ELSEIF( ${ARG} STREQUAL "LIBS" )
SET(__MODE "LIBS")
ELSE( ${ARG} STREQUAL "SOURCES" )
##
## source
##
IF( ${__MODE} STREQUAL "SOURCES")
SET(${APPNAME}_SRCS ${${APPNAME}_SRCS} ${ARG}) # append to var
ENDIF( ${__MODE} STREQUAL "SOURCES")
##
## libs
##
IF( ${__MODE} STREQUAL "LIBS")
SET(${APPNAME}_LIBS ${${APPNAME}_LIBS} ${ARG}) # append to var
ENDIF( ${__MODE} STREQUAL "LIBS")
ENDIF( ${ARG} STREQUAL "SOURCES" )
ENDFOREACH(ARG)
QT4_AUTOMOC(${${APPNAME}_SRCS})
add_executable(${APPNAME} ${${APPNAME}_SRCS})
target_link_libraries(${APPNAME} ${${APPNAME}_LIBS})
ENDMACRO(BIOSCALE_QUICKAPP)
## Configuration for all targets
SET (bioreader_SRCS src/universal.cpp)
# Executable target for unit tests
BIOSCALE_QUICKAPP (unittest
SOURCES ${bioreader_SRCS}
LIBS ${bioreader_reader_LIBS})
# Executable target for reader
BIOSCALE_QUICKAPP (reader
SOURCES ${bioreader_SRCS}
LIBS ${bioreader_reader_LIBS})
IF(PROFILING)
SET_TARGET_PROPERTIES(reader PROPERTIES LINK_FLAGS -pg)
ENDIF(PROFILING)
This is a big post and I may not get to answering all of it in one shot. But, I will start at the top and try to answer what I come across. It seems like any understanding will get you farther than you are. Who knows, maybe I'll even answer the real question.
Q1) "Nowhere in the CMakeLists.txt file is the variable bioreader_common_LIBS defined "
A1)
SET(bioreader_common_LIBS ${bioreader_common_LIBS} QtCore QtScript .... )
is defining bioreader_common_LIBS. What the set call is doing is saying, "Set bioreader_common_LIBS to whatever it's currently defined as ( note the syntx ${ .. } which gives you the value of the variable. ) plus what ever follow, e.g. the Qt libs. You can see how that same type of line is used lowe in your file, that is appending to the current value of bioreader_common_LIBS
Q2) bioreader_common_LIBS defined and its not contained in the cache.
A2) To add it to the cache, the set call would look like ..
set(bioreader_common_LIBS ${bioreader_common_LIBS} lib1 lib2 CACHE STRING "")
Q3 A3) The 'Useful CMake variables' are set by CMake when appropriate and and won't exist in your CMakeLists.txt necessarily, unless you are setting them to something you need. Id you want to see the value of any variable, try, e.g.
message( "var_name: ${var_name}" )
to see the value of var_name. Those messages will print when you configure the project.
Q4) The rest ...
A4) One thing to remember is, every subdirectory has a CMakeLists.txt file in that controls configuring/building the libraries therein.
To find your libraries, follow the example of Boost in your CMakeLists. Use a find_package(MySQL REQUIRED) call with your correct package name. You can find the CMake supplied Modules in the CMake_install_directory/Modules. If there isn't one, then you'll need to write it. Find modules provide several useful variable when then succeed. They are described in the file usually, but roughly you'll get ( using MySQL as the example ) MySQL_FOUND - tells if CMake found it, MySQL_INCLUDE_DIR - the path the headers, MySQL_LIBRARIES and/or MySQL_LIBRARY - the names of the library(s), MySQL_LIB_DIR - the library directory.
Now, you see in your CMake file, include_directories, you can add
include_directories(${MySQL_INCLUDE_DIR})
to your project to add it to your -I of the compiler args. You can use
link_directories(${MySQL_LIB_DIR})
to add that directory for linking. Now, to link your library, call
target_link_libraries(my_lib ${MySQL_LIBRARIES})
One thing to notice, your current CMake file has some bad habits going on, namely, it explicitly names the libraries to linke. That is not recommended as it binds you pretty tightly to the whims of the library providers. The names can change, so you're better foo always using the variables you're given from the find modules. Also, I don't believe you ever need to add
link_directories (/usr/lib)
since that directory is usually already in the default search path, though I guess it won't hurt to have it.
That should get you moving in the right direction, I've typed for too much for one sitting.
Introduction:
I am trying to use CMake to obtain cross platform compilation scripts (for VS 9.0 on a Windows32 and Makefiles for Unix).
I am experiencing something i can't understand about add_subdirectory().
Let me show you my code :
Context:
My architecture for a module named "module1" is something like this :
CMakeLists.txt
include/
file1.h
file2.h
*.h
src/
file1.cpp
file2.cpp
*.cpp
test/
CMakeLists.txt
src/
testfile1.cpp
testfile2.cpp
The architecture of my whole application is composed of these modules which are in themselves projects that could work independantly.
My goals:
I want to compile my module as a library
I want to test the library with the code in the test/ folder
Here are the CMakeLists i wrote :
This one is the CMakeLists.txt in the root directory of my module.
#ENSURE MINIMUM VERSION OF CMAKE
cmake_minimum_required(VERSION 2.8)
#CONFIGURATION OF THE PROJECT
#NAME OF THE PROJECT
project(MyProject)
#OUTPUT OF THE PROJECT
set(LIBRARY_OUTPUT_PATH lib/${CMAKE_BUILD_TYPE})
#ADD THE HEADERS OF THE LIBRARY BEING CREATED
include_directories(include)
#ADD 3rd PARTY OPENCV LIBRARIES
find_package(OpenCV REQUIRED)
#ADD 3rd PARTY XERCES LIBRARIES
include_directories(${XERCES_INCLUDE_DIR})
link_directories(${XERCES_LIB_DIR})
set(Xerces_LIBS xerces-c_3D.lib)
#CONFIGURATION OF THE LIBRARY
file(GLOB_RECURSE MYPROJECT_MODULE_CXX src/*)
file(GLOB_RECURSE MYPROJECT_MODULE_HDR include/*)
#NAME OF THE PRESENT LIBRARY
set(MYPROJECT_MODULE_LIB_NAME myModuleLib)
add_library(${MYPROJECT_MODULE_LIB_NAME}
SHARED
${MYPROJECT_MODULE_CXX}
${MYPROJECT_MODULE_HDR}
)
target_link_libraries(${MYPROJECT_MODULE_LIB_NAME}
${OpenCV_LIBS}
${Xerces_LIBS}
)
#CONTINUE IN THE SUB FOLDERS
add_subdirectory(test)
And then, in the test/ folder, here is the CMakeLists.txt
#ENSURE MINIMUM VERSION OF CMAKE
cmake_minimum_required(VERSION 2.8)
#CONFIGURATION OF THE PROJECT
#NAME OF THE PROJECT
project(MyProjectTest)
#OUTPUT OF THE PROJECT
set(EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE})
#ADD OUR TESTED LIBRARY
include_directories(../include)
link_directories(../build/lib/${CMAKE_BUILD_TYPE})
#CONFIGURATION OF THE EXE
file(GLOB_RECURSE MYPROJECT_MODULE_TEST_CXX src/*)
#NAME OF THE PRESENT EXECUTABLE
set(MYPROJECT_MODULE_TEST_BIN_NAME myModuleTest)
add_executable(${MYPROJECT_MODULE_TEST_BIN_NAME}
${MYPROJECT_MODULE_TEST_CXX}
)
target_link_libraries(${MYPROJECT_MODULE_TEST_BIN_NAME}
${MYPROJECT_MODULE_LIB_NAME}
)
Question
The CMake outputs a correct MyProject.sln Visual Studio 9.0 solution, which compiles successfully in my library linked with OpenCV and Xerces (and other 3rd part libraries). However the test binary did not output any MyProjectTest.sln.
I thought, (and read in the CMake documentation) that add_subdirectory(dir) was used to do CMake in the following sub directory (i mean, the name could not be clearer :p !), so shouldn't it continue CMake in the test/ directory and create my MyProjectTest.sln solution ?
I use the GUI CMake to run the root CMakeLists.txt in a build directory that i create in the root of my module. When I explore the build directory that's where I can find my MyProjet.sln, a test/ folder, but no MyProjectTest.sln in it !
This may not solve your original problem but in your test/folder/CMakeLists.txt try changing
#ADD OUR TESTED LIBRARY
include_directories(../include)
link_directories(../build/lib/${CMAKE_BUILD_TYPE})
to
#ADD OUR TESTED LIBRARY
include_directories(${CMAKE_SOURCE_DIR}/include)
link_directories(${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE})
otherwise you are assuming that your build folder is always named build.
After three days trying everything, I finally found the answer... Sir DLRdave was right actually: the problem was not from the code itself but from something "out of the code".
Problem found:
I created and edited all my files with Notepad++. Actually when opening the files with windows notepad (because i was curious) a strange rectangle symbol appeared and the file did not look like the one I usually see on Notepad++
I found out that the symbol was a "\n\r" that Notepad++ did not show me (it must be filtered) but going on windows notepad, you could see that the whole file was "impure" and appeared on a single line instead of the layout i saw on Notepad++.
As this "encoding" bug appeared only in the subdirectory CMakeLists, it could not be read but said no error when interpreting with CMake and that's probably why I had no returned error from running CMake.
Solution:
I used the native2ascii.exe tool from Java to correct the encoding error.
The why:
Actually what it probably means is that the syntaxic parser of CMake has probably not been designed for filtering this type of char appearing with strange encoding, that's why it gave me 3 days of intense debugging.