c++ compile multiple cpp files using cmakefile.txt in linux - c++

I am quite new to linux and c++.. i have couple of cpp file and cmakefile.txt in my source folder. how can i compile in ubuntu with g++ (multiple cpp files)
I have this CMakeList.txt
project(Test)
# link_libraries($Nest_LIBRARIES})
subdirs(
#
engine
options
ui
# jni
)
#build the Test library
add_library(test STATIC
options/command_line_options.cpp
options/options_map.cpp
utility/timer.cpp
utility/generics/any.cpp
util/hdfs.cpp
logger/logger.cpp
logger/backtrace.cpp
)
requires_core_deps(test)
INSTALL(TARGETS
test ARCHIVE DESTINATION lib)

This is CMake (tutorial). Some say it simplifies build process.
Create makefiles from CMake metafiles: cmake . -G "Unix
Makefiles"
Run make: make -j2 install

Related

How do I change the name of the executable that I'm installing using CPack?

I do apologize in advanced if this sounds like something trivial. I am new to using CMake and CPack.
I am currently trying to build my own compiler as a side project, and I want to test out how CPack will install my project.
Here is my CMakeLists.txt file that I have at the root of my project folder:
cmake_minimum_required(VERSION 3.15)
project(Simple-C-Compiler VERSION 0.01)
set(CMAKE_CXX_STANDARD 20)
set(COMPILER_VERSION ${PROJECT_VERSION})
add_library(include INTERFACE)
target_include_directories(include INTERFACE include/)
add_subdirectory(lib)
add_subdirectory(phases)
add_subdirectory(compiler)
add_subdirectory(tests)
target_link_libraries(compiler lexer)
target_link_libraries(tester lexer)
add_compile_options(-Wall)
install(TARGETS compiler DESTINATION bin)
set(CPACK_PACKAGE_EXECUTABLES "compiler" "Simple-C")
include(CPack)
When I try to install my compiler, by doing:
mkdir build
cd build
cmake ../
make install
I get the following output:
[ 22%] Built target lib
[ 55%] Built target lexer
[ 77%] Built target compiler
[100%] Built target tester
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/bin/compiler
CPack installed my compiler as "compiler" not "Simple-C". I want the name of the executable being installed to be "Simple-C". How do I go about doing that in my CMakeLists.txt file?
You can change the name of a target with the following command:
set_target_properties(compiler PROPERTIES OUTPUT_NAME Simple-C)
This must be called after the add_subdirectory(compiler)
As a side note, the commands you mentionned did not invoke cpack. In order to invoke cpack, you would need to run the cpack command.
You can use the RENAME option of CMake install. See https://cmake.org/cmake/help/v3.13/command/install.html
In short
install(TARGETS compiler DESTINATION bin RENAME Simple-C)

cpprestsdk using vcpkg, cmake - can't find include files

I am porting a Windows project to CentOS Linux that uses cpprestsdk. I use vcpkg on Windows and I thought I would use vcpkg (and cmake) to bring in and build the packages and 'expose' the libs and header files to my project. The sequence fails in trying to get package header file 'known' to my source. This is what I did.
$ vcpkg install boost cpprestsdk
$ vcpkg integrate install
Applied user-wide integration for this vcpkg root.
CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake"
$ cd <source>
$ vi CMakeLists.txt
cmake_minimum_required(VERSION 2.8.9)
project(Domain)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -I../ ")
file(GLOB SOURCES "*.cpp")
#Generate the shared library from the sources
add_library(Domain SHARED ${SOURCES})
install(TARGETS Domain DESTINATION ../lib)
$ cmake -DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake -G "Unix Makefiles" .
$ make
[ 7%] Building CXX object CMakeFiles/Domain.dir/BaseDataFactory.cpp.o
In file included from /src/Domain/stdafx.h:4:0,
from /src/Domain/BaseDataFactory.cpp:1:
../Common/Common.h:75:26: fatal error: cpprest/json.h: No such file or directory
#include <cpprest/json.h>
By adding the vcpkg toolchain file parameter to cmake, I thought it was supposed to take care of exposing all of the package paths (lib/header) and write them to the output Makefile?
I tried adding
find_package(cpprestsdk REQUIRED)
Then I got bunch of new errors:
CMake Error at CMakeLists.txt:7 (find_package):
Could not find a package configuration file provided by "cpprestsdk" with
any of the following names:
cpprestsdkConfig.cmake
cpprestsdk-config.cmake
cpprestConfig.cmake
cpprest-config.cmake
cpprestsdk-config.cmake does exist under the vcpkg root directory and I can definitely see the offending header file for the package under the vcpkg root directory, but why does the cmake-generated Makefile not have everything it needs to build? Does each and every package under vcpkg have to be manually included in some way in the CMakeLists.txt file?
I found the problem. Cpprestsdk does not register/expose any cmake find_package() config module. If it did that, this wouldn't be an issue - the generated toolchain file would set everything cmake needs in order to generate the paths to include in the MakeFile.
I added the following line to the CMakeList.txt file and cmake was then able to find the config file:
set(cpprestsdk_DIR "/vcpkg/installed/x64-linux/share/cpprestsdk")
Which is really, really bad, IMHO, to have to hard code a path to find cpprestsdk. I still have the header file path problem, so there's actually much more going wrong/missing. I'll update this post once I get word from the vcpkg/cmake teams.
https://github.com/Microsoft/cpprestsdk/blob/ea4eff7cd1d6110833df869f7591f266816f8328/Release/src/CMakeLists.txt#L282-L285
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/cpprestsdk-config.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/${CPPREST_EXPORT_DIR}
)
and
https://github.com/Microsoft/cpprestsdk/blob/9d8f544001cb74544de6dc8c565592f7e2626d6e/Release/CMakeLists.txt#L22
set(CPPREST_EXPORT_DIR cpprestsdk CACHE STRING "Directory to install CMake config files.")
One thing puzzle me (not a vcpkg expert yet)
https://github.com/Microsoft/vcpkg/blob/master/ports/cpprestsdk/portfile.cmake#L45
vcpkg_fixup_cmake_targets(CONFIG_PATH lib/share/cpprestsdk)
while it should be lib/cpprestsdk IMHO (ed: not checked SHA1 version)
#cardinalPilot did you try to locate the config file on your system ?
can you also try to print the CMAKE_PREFIX_PATH etc to see if vcpkg do correctly its stuff...

Using cmake on windows without IDE

this might be a duplicate, but I've already spent a couple of hours searching for an answer... without solution. First of all I know this problem might not exist if I'd use a Linux, but I am on Windows.
I am pretty new to c++ but already got some experience with java and gradle. I try to use cmake just like I am used to use gradle. I already read the cmake wiki, but I either do not find the correct pages or I just don't understand it. Here is my directory structure:
MyProject
-bin
-include
--header1.h
--header2.h
--header3.h
--header4.h
--header5.h
--header6.h
-src
--CMakeLists.txt
--MyProjectConfig.h.in
--impl1.cpp
--impl2.cpp
--impl3.cpp
--impl4.cpp
--impl5.cpp
--impl6.cpp
-main.cpp
-CMakeLists.txt
My CMakeLists.txt in my project folder looks like:
cmake_minimum_required (VERSION 3.14)
project (MyProject)
add_subdirectory(src)
file(GLOB_RECURSE sources src/*.cpp include/*.h)
# The version number.
set (Tutorial_VERSION_MAJOR 0)
set (Tutorial_VERSION_MINOR 1)
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/MyProjectConfig.h.in"
"${PROJECT_BINARY_DIR}/MyProjectConfig.h"
)
# add the binary tree to the search path for include files
# so that we will find MyProjectConfig.h
include_directories("${PROJECT_BINARY_DIR}")
install (FILES "${PROJECT_BINARY_DIR}/MyProjectConfig.h"
DESTINATION include)
add_executable(MyProject main.cxx ${sources})
# add the install targets
install (TARGETS MyProject DESTINATION bin)
My CMakeLists.txt in the src folder looks like:
cmake_minimum_required (VERSION 3.14)
include_directories(${MyProject_SOURCE_DIR}/MyProject/include)
I use the command in the bin bin directory: cmake -G "MinGW Makefiles" -S ../src
I got 2 questions now:
(How do I tell cmake to always use MinGW? ( I don't want to use -G always)) solved
(The compiled file build\CMakeFiles\3.14.0-rc2\CompilerIdCXX\a.exe does not have the expected behavior. It should print "Hello world!" and "My Class", while "My Class" is printed from the attribute of a class created from impl1.cpp, however it does nothing.) needs clarification:
How do I build a windows .exe-file to ruin on the console?
Edit:
I have learned that I have to call cmake --build . in my bin directory after creating the cmake files. However I just don't get an exe-file. With flag -v I get this output:
"C:\Program Files\CMake\bin\cmake.exe" -SD:\git\MyProject\src -BD:\git\MyProject\bin --check-build-system CMakeFiles\Makefile.cmake 0
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_progress_start D:\git\MyProject\bin\CMakeFiles D:\git\MyProject\bin\CMakeFiles\progress.marks
C:/MinGW/bin/mingw32-make.exe -f CMakeFiles\Makefile2 all
mingw32-make.exe[1]: Entering directory 'D:/git/MyProject/bin'
mingw32-make.exe[1]: Nothing to be done for 'all'.
mingw32-make.exe[1]: Leaving directory 'D:/git/MyProject/bin'
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_progress_start D:\git\MyProject\bin\CMakeFiles 0 ```
Using the -G option is the standard way of doing it. It prevents you from having to put system-specific settings into your CMake config (like the hardcoded paths to MingW) and lets you use other compilers without having to change build scripts.
The a.exe you started is not your build output. It should be called MyProjectExec.exe. Also, you need to specify all source files in your call to add_executable. add_subdirectory does not automatically add any source files (to what build output should it add them?), it just executes the CMakeLists.txt.

CMake does not produce .exe file

I have built a CERN's ROOT script which based on c++ and i write(edit an example) CMakeList.txt. I am so rokie at CMake btw.
When I command to compile with cmake .., it done correctly -i think- with no errors. But .exe file what i want to produce does not appear.
My directory orders
/Project
../TLV.cpp
../CMakeLists.txt
../build
There is my CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(TLV)
#Set CXX flags to compile with c++11 and error warnings quiet
set(CMAKE_CXX_FLAGS "-O3 -fPIC -Wall -Wextra -std=c++11 -m64")
#Load root
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} $ENV{ROOTSYS}/etc/cmake)
#print conf
message(STATUS "Environmental CMAKE_MODULE_PATH is $ENV{ROOTSYS}")
#find the package with extra libraries needed
find_package(ROOT MODULE REQUIRED Cling TreePlayer Tree Rint Postscript Matrix RIO Core Foam RooStats RooFit RooFitCore Gpad Graf3d Graf Hist Net TMVA XMLIO MLP)
#include ROOT stuff
include(${ROOT_USE_FILE})
message(STATUS "Environmental ROOTSYS is $ENV{ROOTSYS}")
message(STATUS "found root at: ${ROOT_USE_FILE}")
message(STATUS "ROOT_LIBRARIES=${ROOT_LIBRARIES}")
#produce executables in bin path
set(EXECUTABLE_OUTPUT_PATH bin)
#include_directories(./../Framework Headers)
#${FROM_OTHERS_INCLUDE})
#defines all .cpp support class with corresponding Headers
#file(GLOB SRCS Sources/*.cpp Headers/*.hpp )
#${FROM_OTHERS_HEADER} ${FROM_OTHERS_SOURCE})
#add executable
add_executable( TLV TLV.cpp )
#link the executable with the root libraries
target_link_libraries(TLV ${ROOT_LIBRARIES})
I do not get it where I am wrong.
A typical scenario on a project which uses cmake is
cd src_directory # for example cd ~/src/root-6.08.06/
mkdir build # skip this if dir build already exists
cd build
cmake .. # the .. just says your source home dir is up a dir
cmake-gui .. # (optional) skip this unless you need a GUI alternative to cmake where you can edit settings
cmake --build # if you have a quad core CPU could use: make -j8 ... or make -j $(nproc) # on linux
then launch binary and confirm its OK then if desired install it using
sudo make install

How to build gtest static library from my project CMakeLists.txt?

I have a main project with a subproject tests.
In project/CMakeLists.txt I added
add_subdirectory(tests)
In project/tests/CMakeLists.txt I plug in "pre-compiled" gtest library (from Ubuntu repository). I cd to /usr/src/gtest and compile two *.a files into system lib directory.
And it works fine, until issue scribed in google test FAQ appeared.
How to build gtest static library files from project/tests/CMakeLists.txt and how to use this new *.a files instead of system ones?
Finaly I find out how to rebuild static libgtest.a without adding googletest as a subproject.
Using info from this link and from the bottom of this link.
Interesting part of my project/tests/CMakeLists.txt:
.....
# Locate GTest
#find_package(GTest REQUIRED)
#include_directories(SYSTEM ${GTEST_INCLUDE_DIRS})
set(GTEST_SRC /usr/src/gtest/src/gtest-all.cc)
include_directories(SYSTEM /usr/src/gtest # <-- path to non-header files from gtest-all.cc
/usr/include) # <-- path to gtest headers
add_library(gtest STATIC ${GTEST_SRC}) # <-- make static library target before main project executable
target_link_libraries(gtest ${CMAKE_THREAD_LIBS_INIT})
# Link runTests with what we want to test and the GTest and pthread library
add_executable(tests ${SRC})
target_link_libraries(tests ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} gtest) # <-- finaly link this library as others
I'm starting from beginning.
First, download the googletest source code from
https://github.com/google/googletest
When we download this ZIP-files, we get the googletest and googlemock project, but here I will only use the googletest folder. I unpack the ZIP and copy the googletest folder to my project, e.g.:
/home/name/myProject/
The content from this folder could look like the following:
- CMakeLists.txt
- googletest /
- main.cpp
In the CMakeList file I can add gtest as a subdir and link my executable against it. I build a minimal example:
cmake_minimum_required(VERSION 2.6.4)
project(MyProject)
enable_testing()
add_subdirectory( googletest )
# this sets the output dir to /bin
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
include_directories(${CMAKE_SOURCE_DIR}/googletest/include)
add_executable(myExe main.cpp)
target_link_libraries(myExe gtest_main gtest)
The last three lines set the include path to googletest, add the executable and link the exe against gtest.
After downloading gtest and creating the cmake structure, you can build you program:
$ mkdir bin
$ cd bin
$ cmake ..
$ make
and call the exe:
$ ./myExe
I hope this will help.