Adding library reference to NewT in CMake CMakeLists.txt - c++

I am trying to make a simple TUI using newt. I have installed the newt-dev package: apt-get install libnewt-dev and I beleive it is installed correctly since if I do build using gcc with following commands, it works just fine:
gcc -o test main.cpp -lnewt
But my simple code does not compile when I try with cmake using new CLion IDE. Here are the source code, CMakeLists.txt and compiler output:
#include <newt.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[])
{
/* required variables and string */
int uiRows, uiCols;
const char pcText[] = "Welcome to Newt and FLOSS !!!";
/* initialization stuff */
newtInit();
newtCls();
/* determine current terminal window size */
uiRows = uiCols = 0;
newtGetScreenSize(&uiCols, &uiRows);
/* draw standard help and string on root window */
newtPushHelpLine(NULL);
newtDrawRootText((uiCols-strlen(pcText))/2, uiRows/2, pcText);
/* cleanup after getting a keystroke */
newtWaitForKey();
newtFinished();
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.1)
project(TemparatureMonitoring)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_library(newt) #this does nothing!
set(SOURCE_FILES main.cpp)
add_executable(TemparatureMonitoring ${SOURCE_FILES})
Compiler output:
/opt/clion-1.0/bin/cmake/bin/cmake --build /home/saeid/.clion10/system/cmake/generated/9c100db8/9c100db8/Debug --target all -- -j 4
You have called ADD_LIBRARY for library newt without any source files. This typically indicates a problem with your CMakeLists.txt file
-- Configuring done
CMake Error: Cannot determine link language for target "newt".
CMake Error: CMake can not determine linker language for target: newt
-- Generating done
-- Build files have been written to: /home/saeid/.clion10/system/cmake/generated/9c100db8/9c100db8/Debug
make: *** [cmake_check_build_system] Error 1
I think I have to somehow add a reference to newt package, but no idea how! So basically I am looking for a equivalent to -l switch of gcc for CMakeLists.txt

In addition to my comment, after searching a little bit, I think you need the command ''target_link_libraries''
http://www.cmake.org/cmake/help/v3.0/command/target_link_libraries.html

Related

CMake + ninja - exe file shows no output if header file is included in a source file

I am learning to use CMake and I'm using ninja as a build system. I have created a very simple program, but I have one issue. I have only two files main.cpp and constants.h. Whenever I include constants.h in main.cpp, after building a .exe file, I see no output from it after running it through bash. When i remove the include, it works just fine. Can anybody please guide.
main.cpp
#include <stdio.h>
#include "constants.h" // does not even show output when i add this
int main() {
printf("hello world");
return 0;
}
constants.h
#pragma once
const int WIDTH = 1000;
CMakeLists.txt
cmake_minimum_required(VERSION 3.23)
set(CMAKE_CXX_COMIPLER "g++")
set(CMAKE_C_COMPILER "gcc")
project(BoidSimulation)
set(CMAKE_CXX_STANDARD 17)
add_executable(BoidSimulation main.cpp)
Can someone please guide what I'm doing wrong. I have tried to add constants.h in add_exectuable and also used target_include_directories by keeping the header file in some directory.
I build and run through the following commands:
cmake -G "Ninja" -S . -B ./out/build/
cd out/build
ninja
./BoidSimulation
Running this with header file shows no output and no errors on bash, it just moves on to next line. It runs fine through powershell and shows the output with or without header files.
You never print a newline. In some shells this will cause the prompt to be printed over it. This has nothing to do with your constants.h header.

How to include 'jni.h' file using CMake [duplicate]

This question already has answers here:
How to use FIND_JNI on cmake
(2 answers)
Closed 9 months ago.
I am trying to compile my C++ project using CMake on my Mac M1 Pro 12.0.1.
This is my simple directory structure:
In my foo.cpp, I am including jni.h header file:
#include <iostream>
#include "foo.h"
#include <vector>
#include <jni.h>
void foo()
{
std::cout << "Hello World!\n";
}
This is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.4.1)
project("myapplication")
add_library(my_app SHARED main.cpp foo.cpp)
target_include_directories(my_app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
if(APPLE)
set(JAVA_INCLUDE_PATH "$ENV{JAVA_HOME}/include")
set(JAVA_INCLUDE_PATH2 "$ENV{JAVA_HOME}/include/darwin")
set(JAVA_AWT_INCLUDE_PATH "$ENV{JAVA_HOME}/include")
message("JAVA_INCLUDE_PATH = ${JAVA_INCLUDE_PATH}")
find_package(JNI REQUIRED)
if (JNI_FOUND)
message (STATUS "JNI_INCLUDE_DIRS=${JNI_INCLUDE_DIRS}")
message (STATUS "JNI_LIBRARIES=${JNI_LIBRARIES}")
endif()
target_include_directories(my_app PUBLIC ${JNI_INCLUDE_DIRS})
endif()
I am getting CMake output as:
-- Found JNI: /System/Library/Frameworks/JavaVM.framework
-- JNI_INCLUDE_DIRS=/Users/vmangal/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/include;/Users/vmangal/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/include/darwin;/Users/vmangal/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/include
-- JNI_LIBRARIES=/System/Library/Frameworks/JavaVM.framework;/System/Library/Frameworks/JavaVM.framework
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/vmangal/my/practice/cmake/build
My JAVA_HOME environment variable is set to /Users/vmangal/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk
But during make command, I am getting compilation error:
/Users/vmangal/my/practice/cmake/foo.cpp:4:10: fatal error: 'jni.h' file not found
#include <jni.h>
Am I missing something in CMakeLists.txt ?
I had a similar problem and found that when setting variables this way
set(JAVA_INCLUDE_PATH "$ENV{JAVA_HOME}/include")
i was getting wrong imports for C_INCLUDES and CXX_INCLUDES. Like this (see in CMakeFiles/my_app.dir/flags.make):
C_INCLUDES = -I/include -I/include/darwin
CXX_INCLUDES = -I/include -I/include/darwin
Which basically which meant that $ENV{JAVA_HOME} was an empty string.
After I set the full paths in CMakeLists
set(JAVA_INCLUDE_PATH /usr/local/Cellar/openjdk#17/17.0.3/libexec/openjdk.jdk/Contents/Home/include)
everything started working correctly.
So the conclusion is that if you want to run cmake and use $ENV{JAVA_HOME} – use syntax JAVA_HOME=/path/to/java/home cmake ...

cmake: add directory to be searched for header files

I am writing c++ code to run tests on an arduino project I've written. In order to run it, I need it to include mockups of a couple libraries (the original libraries don't work in c++). The mockups are in my src directory, along with the tests in main.cpp. The files that rely on the mockups are in the parent directory of src, and I cannot modify them to refer to src without breaking their ability to run when uploaded to an arduino. I also cannot add the mockups or main.cpp to the parent directory, as this would interfere with the operation of the arduino code.
So, I need to add the child directory with the mockups to the directories that are searched when compiling the files in the parent directory.
Directory Outline:
parent
forTest.h
forTest.cpp
src
parson.h
parson.c
String.h
String.cpp
main.cpp
CMakeLists.txt
build
In this case, main.cpp has "#include ../forTest.cpp", and forTest.cpp has "#include parson.h" and "#include String.h"
I am currently running the following code in CMakeLists.txt:
cmake_minimum_required (VERSION 2.6)
project(makeTest)
include_directories(../ )
set (makeTest_VERSION_MAJOR 1)
set (makeTest_VERSION_MINOR 0)
add_executable(makeTest main.cpp ../forTest.cpp String.cpp parson.c)
I then build it in the build directory from the command line with
cmake -G "Unix Makefiles" ../src
make
The cmake command resolves successfully, but the make command hits "fatal error: parson.h not found" when building forTest.cpp
How can I resolve this?
edit: my apologies if this has an obvious answer, I'm very new to Cmake
edit the second: using the changes suggested by Gergely Nyiri and changing #include to #include "/usr/include/string.h" resolves several errors, but introduces a new error : "implicit instantiation of undefined template" during the make step.
It refers to the following code in by string.h mockup file:
#ifndef STRING_H
#define STRING_H
#include "/usr/include/string.h"
using namespace std;
class String {
private:
std::string thisString;
char chars[];
...
#endif
which returns the error:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/cstring:61:
/Users/douglas/Desktop/parts/makeHolder/testMake/src/string.h:9:14: error:
implicit instantiation of undefined template 'std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> >'
std::string thisString;
This is followed by:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/iosfwd:193:32: note:
template is declared here
class _LIBCPP_TEMPLATE_VIS basic_string;
First of all, I would propose to put CMakeLists.txt in your source root. Then:
cmake_minimum_required (VERSION 2.6)
project(makeTest)
include_directories(src)
set (makeTest_VERSION_MAJOR 1)
set (makeTest_VERSION_MINOR 0)
add_executable(makeTest src/main.cpp forTest.cpp src/String.cpp src/parson.c)
Configure & build:
cd build
cmake ../
make
Even better if you use target_include_directories instead of include_directories:
..
add_executable(makeTest src/main.cpp forTest.cpp src/String.cpp src/parson.c)
target_include_directories(makeTest PRIVATE src)

Can clang static analyzer (scan-build) be used with cmake --build?

I'd like to use the clang static analyzer command line tool scan-build with the convenience of cmake --build.
Most of the resources I found online seem to indicate you need a two-step process:
scan-build cmake .
scan-build make
For example for this small example program with a bug that scan-build catches:
#include <iostream>
int fun() {
int x;
return x; # main.cpp:5:5: warning: Undefined or garbage value returned to caller
}
int main() {
int a = fun();
std::cout << "Hello, World! " << a << std::endl;
}
CMakeLists.txt:
cmake_minimum_required(VERSION 3.5)
project(test_program)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(test_program ${SOURCE_FILES})
If I run scan-build cmake --build cmake-build-release/ it does not find the bug, even though the binary is built. Is there anyway to get scan-build to work in a one step process with CMake?
If you want to use the Clang Static Analyzer, you should just set CMAKE_EXPORT_COMPILE_COMMANDS=YES. This will create a compilation database that CSA can read. You don't even need to build your project. The file is located at: /path/to/build/compile_commands.json.
scan-build is designed for projects that can't create a compilation database themselves.
Then you can run:
analyze-build --cdb /path/to/build/compile_commands.json \
--use-analyzer /path/to/clang \
--output /path/to/output
It's worth noting that clang-tidy has all of the CSA checks now. You can use this same compilation database technique to run clang-tidy on your codebase.

CMake project for Emscripten

I want to make CMake and Emscripten friends. Didn't find more or less informative documentation on the Emscripten project website, but they provide CMake toolchain file so I think it should be possible.
So far very basic compilation without advanced parameters works fine, but I have issues while using embind and preloading files.
Linking process seems to miss Emscripten "binaries" and produces warnings for all embind related functions like this one: warning: unresolved symbol: _embind_register_class which results in respective errors while loading compiled JS file in rowser.
No .data file is generated during the compilation.
I've created a minimalistic example which includes two targets: one "normal" (client) and one manual (manual-client) which simply runs emcc as I expect it to be run: https://github.com/xwaffelx/minimal-cmake-emscripten-project/blob/master/README.md
Although manual way works, I don't think it is a proper way to do it...
--- Update ---
As requested, here is even more short example:
CMakeLists.txt file
cmake_minimum_required(VERSION 2.8)
cmake_policy(SET CMP0015 NEW)
project(emtest)
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build.emscripten)
include_directories("lib/assimp/include")
link_directories("lib/assimp/lib-js")
link_libraries("assimp")
file(GLOB_RECURSE CORE_HDR src/.h)
file(GLOB_RECURSE CORE_SRC src/.cpp)
add_definitions("-s DEMANGLE_SUPPORT=1 --preload-file ${CMAKE_SOURCE_DIR}/assets --bind")
add_executable(client ${CORE_SRC} ${CORE_HDR})
Result should be equivalent to running the following command manualy:
emcc
-Ilib/assimp/include
-s DEMANGLE_SUPPORT=1
--preload-file assets
--bind
Application.cpp
lib/assimp/lib-js/libassimp.so
-o client.js
Here is the Application.cpp:
#include "Application.h"
#include <iostream>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
void Application::Initialize() {
std::cout << "Initializing application." << std::endl;
Assimp::Importer importer; // For test purpose
}
void Application::SayHello() {
std::cout << "Hello!" << std::endl;
}
and Application.h:
#ifndef APPLICATION_H
#define APPLICATION_H
#include <emscripten/html5.h>
#include <emscripten/bind.h>
namespace e = emscripten;
class Application {
public:
void Initialize();
void SayHello();
};
EMSCRIPTEN_BINDINGS(EMTest) {
e::class_<Application>("Application")
.constructor()
.function("Initialize", &Application::Initialize)
.function("SayHello", &Application::SayHello);
}
#endif
THen I run cmake as follows:
cmake -DCMAKE_TOOLCHAIN_PATH=path/to/Emscripten.cmake .. && make
However, warnings like warning: unresolved symbol: _embind_register_class are produced during linking and running the code and no preloaded data in client.data file is created while compiling CMake project. At the same time no warnings and everything runs OK while compiling manually.
The solution was to specify all the flags during the linking by providing following CMake instruction:
set_target_properties(client PROPERTIES LINK_FLAGS "-s DEMANGLE_SUPPORT=1 --preload-file assets --bind")
Thanks to developers of emscripten who helped in the github issues tracker.