UnitTest++ and g++ - Relative path to the library - g++

I'm trying to get UnitTest++ to work in a project following this directory tree:
Project/
|-- src/
|-- test/
| |-- test.cpp
|-- unittest-cpp/
| |-- UnitTest++/
| |-- libUnitTest++.a
| |-- src/
| |-- UnitTest++.h
|-- Makefile
I'm trying to compile with g++ while in the Project directory. My test.cpp file contains the UnitTest++ Getting Started code.
I tried the following:
g++ -Lunittest-cpp/UnitTest++/ -lUnitTest++ -Iunittest-cpp/UnitTest++/src/ \
test/test.cpp -o Test
If I understand well, -L is to give the path to the static library. -l (Small L) is for the library name and -I (Capital i) is for the include path.
I get two different results. It either tells me it cannot find the lib in /usr/bin/??? or it tells me that there are undefined references to unittest::*.
Is it because I'm giving a relative path to the library that it cannot compile? I'm new to using g++ through multiple directories and I'm trying to understand how it works before getting it to work in my Makefile.
[EDIT]: The test/test.cpp parameter had to be given before linking the libraries and headers. So, this worked:
g++ test/test.cpp -Lunittest-cpp/UnitTest++ -lUnitTest++ -Iunittest-cpp/UnitTest++/src -o Test

The file to compile (in this context test.cpp) has to be given before its dependancies when compiling. This worked:
g++ test/test.cpp -Lunittest-cpp/UnitTest++ -lUnitTest++ -Iunittest-cpp/UnitTest++/src -o Test

If you are using this project structure, you can use Cmake that helps to link all the libraries to the target.
target_link_libraries(Target_name All_the_libraries_you_want_to_link)

Related

Is it possible to set output directory of EXPORT_COMPILE_COMMANDS without changing the BINARY_DIR?

CMake generates compile_commands.json in cmake build directory which means that my installation of YouCompleteMe or YCM cannot find it. For YCM to use it I need to move it from the build directory to the source or top level of the project.
Project
|- CMakeLists.txt
|- compile_commands.json (there is what i want)
|- build (this iw where i build my project)
|-- compile_commands.json (this is what i have)
|-- OtherCmakeGenerateStuff
|- src
|-- CMakeLists.txt
|-- main.cc (includes library not in project)
|-lib
|-- CMakeLists.txt
|-- math
|--- CMakeLists.txt
|--- math.cc
|--- math.hh
|-include
|-- globals.hh
|-- definitions.hh
There may be mistakes in these files as I just typed it and haven't tested it. however, my focus is on the top level CMakeLists.txt file.
CMakeLists.txt (Top level)
cmake_minimum_require(VERSION 3.8)
project(just_some_project LANGUAGES CXX VERSION 1.0)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_subdirectory(src)
add_subdirectory(lib)
include_directories(include)
src/CMakeLists.txt
cmake_minimum_require(VERSION 3.8)
project(just_some_project LANGUAGES CXX VERSION 1.0)
find_project(someotherlibrary REQUIRED)
add_executable(main main.cc)
target_include_directories(main PUBLIC math someotherlibraryfound)
lib/CMakeLists.txt (Top level)
cmake_minimum_require(VERSION 3.8)
file(GLOB Headers "*.hh")
file(GLOB Sources "*.cc")
add_library(math STATIC $Sources $Headers)

CMake: avoid building tests by default [duplicate]

I have a small project with cmake. I build a lib and an executable. on the development machine I want also an executable that cannot be build on other machines/environments.
e.g.:
<my-lib>
| -- CMakeLists.txt
|
+ -- src/ -> build the lib/archive
| |-- lib.c
| |-- lib.h
| |-- CMakeLists.txt
|
+ -- tool -> build the tool
| |-- tool.c
| |-- CMakeLists.txt
|
+ -- tests -> build the unit tests
| |-- tests.c
| |-- CMakeLists.txt
I added CMakeLists.txt to all directories. Also an add_executable to the tests. Now the unit-test executable is build by default. But I want to exclude it from default target.
CMakeLists.txt in tests:
find_library (CUNIT_LIB cunit)
include_directories (${Cunit_INCLUDE_DIRS} "${PROJECT_SOURCE_DIR}/src")
set (CMAKE_C_FLAGS "-O2 -Wall -Werror")
add_executable (unit-test tests.c)
target_link_libraries (unit-test my-lib cunit)
Has anyone a hint how to handle this? I don't want to build unit-test always!
There is a property EXCLUDE_FROM_ALL for such task.
You can write:
set_target_properties(unit-test PROPERTIES EXCLUDE_FROM_ALL TRUE)
This is very simple: protect creation of executable by introducing an option/variable.
if (DEFINED WITH_UNIT_TEST)
find_library (CUNIT_LIB cunit)
include_directories (${Cunit_INCLUDE_DIRS} "${PROJECT_SOURCE_DIR}/src")
set (CMAKE_C_FLAGS "-O2 -Wall -Werror")
add_executable (unit-test tests.c)
target_link_libraries (unit-test my-lib cunit)
endif ()
Now when invoking CMake, one would have to explicitly specify -DWITH_UNIT_TEST, so that unit-test target is built, while by default it will never be build. For alternative approach, see comments.

CMake's find_package does not find library added with add_subdirectory

I'm building a test project to learn libraries zeromq with cppmq, and I want to include both libraries as subdirectories. I currently have the following structure:
|-- CMakeLists.txt
|-- deps
| |-- cppzmq-4.3.0
| | |-- CMakeLists.txt
| | `-- rest of files
| |-- zeromq-4.3.1
| | |-- CMakeLists.txt
| | `-- rest of files
`-- main.cpp
I've tried with the following CMakeLists:
cmake_minimum_required(VERSION 3.14)
project(PruebaZeroMQ)
set(CMAKE_CXX_STANDARD 11)
add_subdirectory(deps/zeromq-4.3.1)
add_subdirectory(deps/cppzmq-4.3.0)
add_executable(PruebaZeroMQ main.cpp)
target_link_libraries(PruebaZeroMQ
libzmq
cppzmq)
When I run cmake, I get the following error:
-- Detected CPPZMQ Version - 4.3.0
-- CMake libzmq package not found, trying again with pkg-config (normal install of zeromq)
CMake Error at deps/cppzmq-4.3.0/CMakeLists.txt:20 (message):
ZeroMQ was not found, neither as a CMake package nor via pkg-config
cppmq depends on zeromq, and looks like it tries to load it using find_package, so I tried to modify CMAKE_MODULE_PATH so it could find the ZeroMQConfig.cmake file, but it fails too, with the same error:
add_subdirectory(deps/zeromq-4.3.1)
list (APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_BINARY_DIR}/deps/zeromq-4.3.1 ")
add_subdirectory(deps/cppzmq-4.3.0)
Is there a way of achieving this? I'd rather not install the libraries system-wide.
After trying to manually find_package, CMake showed the following error message:
Add the installation prefix of "ZeroMQ" to CMAKE_PREFIX_PATH or set
"ZeroMQ_DIR" to a directory containing one of the above files.
So I tried that, using:
set(ZeroMQ_DIR ${CMAKE_CURRENT_BINARY_DIR}/deps/zeromq-4.3.1)
And it worked.

How to configure cmake to get an executable not by default

I have a small project with cmake. I build a lib and an executable. on the development machine I want also an executable that cannot be build on other machines/environments.
e.g.:
<my-lib>
| -- CMakeLists.txt
|
+ -- src/ -> build the lib/archive
| |-- lib.c
| |-- lib.h
| |-- CMakeLists.txt
|
+ -- tool -> build the tool
| |-- tool.c
| |-- CMakeLists.txt
|
+ -- tests -> build the unit tests
| |-- tests.c
| |-- CMakeLists.txt
I added CMakeLists.txt to all directories. Also an add_executable to the tests. Now the unit-test executable is build by default. But I want to exclude it from default target.
CMakeLists.txt in tests:
find_library (CUNIT_LIB cunit)
include_directories (${Cunit_INCLUDE_DIRS} "${PROJECT_SOURCE_DIR}/src")
set (CMAKE_C_FLAGS "-O2 -Wall -Werror")
add_executable (unit-test tests.c)
target_link_libraries (unit-test my-lib cunit)
Has anyone a hint how to handle this? I don't want to build unit-test always!
There is a property EXCLUDE_FROM_ALL for such task.
You can write:
set_target_properties(unit-test PROPERTIES EXCLUDE_FROM_ALL TRUE)
This is very simple: protect creation of executable by introducing an option/variable.
if (DEFINED WITH_UNIT_TEST)
find_library (CUNIT_LIB cunit)
include_directories (${Cunit_INCLUDE_DIRS} "${PROJECT_SOURCE_DIR}/src")
set (CMAKE_C_FLAGS "-O2 -Wall -Werror")
add_executable (unit-test tests.c)
target_link_libraries (unit-test my-lib cunit)
endif ()
Now when invoking CMake, one would have to explicitly specify -DWITH_UNIT_TEST, so that unit-test target is built, while by default it will never be build. For alternative approach, see comments.

CMake with "standard" directory layout (Linux)

Let's say I have a simple hello project with the pseudo-standard directory layout
helloworld/
src/
main.c
say.c
say-helper.c
include/
say.h
say-helper.h
build/
and after running
cd ~/helloworld/build
cmake ..
make
I would expect the following
helloworld/
build/lib/
libsay.a
libsay.so
libsay.so.1.0.0
tmp/obj/
main.o
say.o
build/bin/
hello
and after make install I would expect
/usr/local/lib/
libsay.a
libsay.so
libsay.so.1.0.0
/usr/local/bin/
hello
What would the CMakeLists.txt look like for this setup?
I've been looking around for examples, but the only one I've found that shows how to add a library and an executable didn't work.
Basic commands to describe the project:
INCLUDE_DIRECTORIES(include)
ADD_LIBRARY(say src/say.c src/say-helper.c)
ADD_EXECUTABLE(hello src/main.c)
TARGET_LINK_LIBRARIES(hello say)
This is for placing the libs and the executable in the build directory, put that in your CMakeLists.txt:
SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
SET (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
For install you specify
install(TARGETS say hello
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
in your CMakeLists.txt and set CMAKE_INSTALL_PREFIX to /usr/local in your configuration.
I'm not sure if you can build static and dynamic libraries simultaneously with the same name, though. And I don't know how to tell CMake to put the obj files in some specific location.