Setting up a SystemC project with CMake: undefined reference to `sc_core - cmake

I'm trying to build a simple hello world in SystemC with CMake.
Here's the SystemC file main.cpp:
#include <systemc.h>
using namespace std;
SC_MODULE (hello_world) {
SC_CTOR (hello_world) {
}
void say_hello() {
cout << "Hello World SystemC" << endl;
}
};
int sc_main(int argc, char* argv[]) {
hello_world hello("HELLO");
hello.say_hello();
return(0);
}
Here is the CMakeLists.txt:
cmake_minimum_required(VERSION 3.1)
project(SystemCExample)
set (CMAKE_PREFIX_PATH /usr/local/systemc-2.3.2)
include_directories(${CMAKE_PREFIX_PATH}/include)
find_library(systemc systemc ${CMAKE_PREFIX_PATH}/lib-linux64)
link_directories(${CMAKE_PREFIX_PATH}/lib-linux64)
set(CMAKE_CXX_STANDARD 11) # C++11...
set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required...
set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(SystemCExample systemc)
I keep getting the error:
/usr/local/systemc-2.3.2/include/sysc/kernel/sc_ver.h:179: error: undefined reference to `sc_core::sc_api_version_2_3_2_cxx201103L<&sc_core::SC_DISABLE_VIRTUAL_BIND_UNDEFINED_>::sc_api_version_2_3_2_cxx201103L(sc_core::sc_writer_policy)'
It points to sc_ver.h to the line:
api_version_check
(
SC_DEFAULT_WRITER_POLICY
);
The error mesage appears also when I replace the main.cpp with another simple example. How can I fix it?

Most likely you've built SystemC with C++98. It is default. Currently it requires that you use same C++ standard during library build and for your application.
Here are steps to build SystemC 2.3.2 with CMake
Download SystemC 2.3.2, unpack, change directory to systemc-2.3.2
cd /path/to/systemc-2.3.2
Create build directory:
mkdir build
Configure SystemC build with C++11 support. I also recommend to build it in Debug mode, this helps while learning. Later you can switch to Release builds to speed-up simulation
cmake ../ -DCMAKE_CXX_STANDARD=11 -DCMAKE_BUILD_TYPE=Debug
Build
cmake --build .
CMake will automatically export SystemC library targets to User Package Registry: https://cmake.org/cmake/help/v3.0/manual/cmake-packages.7.html#user-package-registry
Optionally you can install it somewhere, read CMake manual to learn how.
Now try to create sample SystemC project:
main.cpp
#include <systemc.h>
SC_MODULE (hello_world) {
SC_CTOR (hello_world)
{
SC_THREAD(say_hello);
}
void say_hello()
{
cout << "Hello World SystemC" << endl;
}
};
int sc_main(int argc, char* argv[])
{
hello_world hello("HELLO");
sc_start();
return (0);
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(test_systemc)
find_package(SystemCLanguage CONFIG REQUIRED)
set (CMAKE_CXX_STANDARD ${SystemC_CXX_STANDARD})
add_executable(test_systemc main.cpp)
target_link_libraries(test_systemc SystemC::systemc)
Build, run, expected output:
./test_systemc
SystemC 2.3.2 --- Oct 14 2017 19:38:30
Copyright (c) 1996-2017 by all Contributors,
ALL RIGHTS RESERVED
Hello World SystemC

Related

CMake add BLAS to project

I'm trying to compile a project with dlib & opencv. I am super new to CMake. It needs a BLAS library included. I have ATLAS installed, I've tried a couple things, but not found any that I can get to work. Is there a way to find a BLAS package installed and add it on Linux (Ubuntu 18.04)? Any help would be much appreciated.
Errors
main.cpp
#include <iostream>
#include <dlib/pixel.h>
#include <dlib/opencv.h>
#include <opencv2/opencv.hpp>
#include <dlib/image_processing.h>
#include <dlib/image_processing/frontal_face_detector.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
cv::Mat frame, half;
cv::VideoCapture cap;
dlib::array2d<dlib::bgr_pixel> dlibFrame;
try
{
cap.open(2);
}
catch(std::exception& e)
{
std::cout << e.what() << std::endl;
return 1;
}
dlib::frontal_face_detector detector;
try
{
std::vector<dlib::rectangle> faces;
cv::namedWindow("Tracking Window");
while(cap.isOpened())
{
cap >> frame;
cv::resize(frame,half,cv::Size(),0.5,0.5);
dlib::assign_image(dlibFrame,dlib::cv_image<dlib::bgr_pixel>(half));
faces = detector(dlibFrame);
for(size_t i = 0;i < faces.size();++i)
{
auto& r = faces[i];
cv::Rect cvr = cv::Rect(r.left(),r.top(),r.width(),r.height());
cv::rectangle(half,cvr,cv::Scalar(255,0,0),2);
}
cv::imshow("Tracking Window",half);
if(cv::waitKey(1) == 27)
break;
}
}
catch(std::exception& e)
{
cout << e.what() << endl;
return 1;
}
cv::destroyAllWindows();
return 0;
}
CMake
cmake_minimum_required(VERSION 3.0.0)
project(ObjectTracking VERSION 0.1.0)
include(CTest)
enable_testing()
add_executable(ObjectTracking main.cpp)
find_package(BLAS REQUIRED)
find_package(OpenCV REQUIRED)
find_package(dlib REQUIRED)
target_link_libraries(ObjectTracking ${OpenCV_LIBS} dlib ${BLAS_LIBRARIES})
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
For Ubuntu 18.04, there are the following packages:
libblas-dev
libbas3
libcblas2
libcublas9.1 (if you have a Nvidia GPU and CUDA?)
I use OpenBLAS, so I'm not positive about which one to use.
An alternative is OpenBLAS. The repo is at: https://github.com/xianyi/OpenBLAS.git
To build it:
git clone https://github.com/xianyi/OpenBLAS.git
cd OpenBLAS
sudo make install
OpenBLAS detects your CPU and creates the appropriate binary.

Linking error for basic Qt5 application using CMake

I am trying to build a simple Qt5 application using CMake
The Qt5 project is the basic project generated when creating a new project with a Widget.
The project builds and runs successfully with QtCreator
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
The CMakeLists file have been written according to the example given in the Qt5 documentation. The path to the Qt5 directory is given in the cache.
http://doc.qt.io/qt-5/cmake-manual.html
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.11)
project(test0)
# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
# Find the QtWidgets library
find_package(Qt5Widgets)
# Tell CMake to create the executable
add_executable(test0 WIN32 main.cpp)
# Use the Widgets module from Qt 5.
target_link_libraries(test0 Qt5::Widgets)
The Cmake generation works fine.
I'm getting linking errors (undefined reference to methods belonging to the Widget class) when building the app using the Makfile generated by Cmake.
(here is a capture of the errors)
http://s31.postimg.org/edefl1m6j/Capturetest0.png
Any tips ?
System :
Windows 7
Compiler :
MinGW32
Versions :
QT 5.6.1 (mingw49_32)
CMake 3.6.0
Two mistakes in the CMakeLists
- widget.cpp has to be mentionend in add_executable as explained Tsyvarev
- use autouic in order to create the ui_widget.h associated with the widget.ui and widget.cpp
The working CMakeLists is the following :
cmake_minimum_required(VERSION 2.8.11)
project(test0)
# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
# Find the QtWidgets library
find_package(Qt5Widgets)
# Tell CMake to create the executable
add_executable(test0 WIN32 main.cpp widget.cpp widget.ui)
# Use the Widgets module from Qt 5.
target_link_libraries(test0 Qt5::Widgets)

Linking to a static lib compiled with MSVC

I'm trying to link with a simple C lib on windows against Rust library
My lib is .h
extern "C" {
void say_hello(const char* s);
}
.cpp
#include <stdio.h>
void say_hello(const char* s) {
printf("hello world");
}
My Rust file
#[link(name="CDbax", kind="static")]
extern "C" {
fn say_hello(s: *const libc::c_char) -> () ;
}
Linking fails by giving an error with one of the data symbols
error: linking with `gcc` failed: exit code: 1
note: "gcc" "-Wl,--enable-long-section-names" "-fno-use-linker-plugin" "-Wl,--nxcompat" "-Wl,--large-address-aware" "-shared-libgcc" "-L" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib" "e:\Rust\DBTools\DBAnalytics\target\debug\DBAnalytics.o" "-o" "e:\Rust\DBTools\DBAnalytics\target\debug\DBAnalytics.dll" "e:\Rust\DBTools\DBAnalytics\target\debug\DBAnalytics.metadata.o" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib\libstd-11582ce5.rlib" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib\libcollections-11582ce5.rlib" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib\librustc_unicode-11582ce5.rlib" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib\librand-11582ce5.rlib" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib\liballoc-11582ce5.rlib" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib\liblibc-11582ce5.rlib" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib\libcore-11582ce5.rlib" "-L" "e:\Rust\DBTools\DBAnalytics\target\debug" "-L" "e:\Rust\DBTools\DBAnalytics\target\debug\deps" "-L" "C:\Program Files (x86)\Rust 1.2\bin\rustlib\i686-pc-windows-gnu\lib" "-L" "e:\Rust\DBTools\DBAnalytics\.rust\bin\i686-pc-windows-gnu" "-L" "e:\Rust\DBTools\DBAnalytics\bin\i686-pc-windows-gnu" "-Wl,-Bstatic" "-Wl,--whole-archive" "-l" "CDbax" "-Wl,--no-whole-archive" "-Wl,-Bdynamic" "-l" "ws2_32" "-l" "userenv" "-l" "advapi32" "-shared" "-l" "compiler-rt"
note: Warning: corrupt .drectve at end of def file
Cannot export ??_C#_0M#LACCCNMM#hello?5world?$AA#: symbol not found
The library is build on MSVC2013 as a simple static lib. The string "hello world" is in the data section, so I wouldn't expect it to cause a link error. Are there some specific settings I need to be aware about when linking with C libraries on windows?
Btw it's 32bit MSVC lib.
Ok, a few things. First of all, there's no such thing as a "static DLL": a DLL is a dynamically linked library.
Secondly, Rust uses the MinGW toolchain and runtime. Mixing MSVC and MinGW runtimes can cause odd things to happen, so it's probably best avoided if at all possible. Rust has only recently landed very early support for building using the MSVC runtime.
However, you can get this specific example to work, apparently without any ill effects. You just need to change a few things:
You need to use a dynamic library; my understanding is that this makes bad interactions a little less likely.
You need to actually compile say_hello with C linkage, not C++ linkage. You did this in the header, but not in the source file.
You need to publicly export say_hello from the library.
Thus:
hello.rs:
#[link(name="hello", kind="dylib")]
extern {
fn say_hello();
}
fn main() {
unsafe { say_hello(); }
}
hello.h:
#ifndef HELLO_H
#define HELLO_H
extern "C" {
__declspec(dllexport) void say_hello();
}
#endif
hello.cpp:
#include <cstdio>
#include "hello.h"
void say_hello() {
printf("hello world\n");
}
build.cmd
cl /LD hello.cpp
rustc -L. hello.rs
On my machine, this produces hello.exe and hello.dll; when run, hello.exe prints out hello world.

Cmake test program cannot find -lgcc_s

I'm using cmake with custom GCC(with shared libraries) and during cmake compiler test I get following error:
The C compiler "/path/to/gcc/bin/gcc" is not able to compile a simple test program.
...
/path/to/gcc/x86_64-unknown-linux-gnu/bin/ld:
cannot find -lgcc_s
Here's a simple "testme.cpp" file:
#include <iostream>
int main( int argc, char * argv[] ) {
std::cout << "Hello world" << std::endl;
return 0;
}
and here's a CMakeLists.txt:
cmake_minimum_required(VERSION 2.6.2)
project(testme)
file( GLOB srcs "testme.cpp" )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -Wall -std=c++11")
set(CMAKE_LDFLAGS "${CMAKE_LDFLAGS} -L/path/to/gcc/lib/gcc/x86_64-unknown-linux-gnu/lib64")
add_executable(testme ${srcs})
to build with my custom GCC I'm exporting CXX and CC:
export CXX=/path/to/gcc/bin/g++
export CC=/path/to/gcc/bin/gcc
and then hit:
cmake .
make
and the result is that it can't find libgcc_s.so which is located in the "lib/gcc/x86_64-unknown-linux-gnu/lib64" folder.
However, when I invoke gcc like this:
/path/to/gcc/bin/g++ testme.cpp -L/path/to/gcc/lib/gcc/x86_64-unknown-linux-gnu/lib64
it compiles successfully. I've tried to add it to LD_LIBRARY_PATH but that doesn't seem to help.
So, is there a way to pass library path to CMake compiler check?
Chrono Kitsune was sort of right ... /path/to/gcc/x86_64-unknown-linux-gnu/bin/ld was build with "--enable-shared" and libraries where not in systems search path.

cmake: linking software to boost::mpi (with mpich2)

For this simple code (taken from the boost-mpi documentation):
#include <boost/serialization/string.hpp>
#include <iostream>
#include <string>
#include <boost/mpi.hpp>
namespace mpi = boost::mpi;
int main(int argc, char *argv[])
{
mpi::environment env(argc, argv);
mpi::communicator world;
if (world.rank() == 0) {
world.send(1, 0, std::string("Hello"));
std::string msg;
world.recv(1, 1, msg);
std::cout << msg << "!" << std::endl;
} else if (world.rank() == 1) {
std::string msg;
world.recv(0, 0, msg);
std::cout << msg << ", ";
std::cout.flush();
world.send(0, 1, std::string("world"));
};
return 0;
};
And for such CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(mpi-tests CXX)
FIND_PACKAGE(Boost 1.4 COMPONENTS mpi serialization REQUIRED)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(test ${Boost_LIBRARIES})
It cannot find boost_mpi:
CMake Error at /usr/share/cmake/Modules/FindBoost.cmake:1135 (message):
Unable to find the requested Boost libraries.
Boost version: 1.47.0
Boost include path: /usr/include
The following Boost libraries could not be found:
boost_mpi
But! I have installed next packages:
boost-graph-mpich2
boost-mpich2
boost-mpich2-devel
boost-mpich2-python
mpich2
mpich2-devel
Why it can't find? There are a plenty examples over Internet where people use FIND_PACKAGE(Boost 1.4 COMPONENTS mpi REQUIRED).
Boost might not be installed in a location that the module FindBoost searches. You can specify the prefix where Boost was installed by setting the variable BOOST_ROOT to your Boost installation prefix.
To your code I would add:
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(mpi-tests CXX)
set( BOOST_ROOT "/path/to/boost/install/prefix" )
FIND_PACKAGE(Boost 1.4 COMPONENTS mpi serialization REQUIRED)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(test ${Boost_LIBRARIES})