I know this topic already has been discussed more than once, but I do not understand what is going wrong. I looked up several websites but none of the provided approaches worked for me.
I want to create a VS solution with CMake which consists of 10 projects. Each project has to link myLibrary.lib.
#CMakeLists.txt:
cmake_minimum_required (VERSION 2.8)
project (Project_Example)
SET(SRC_DIR_PATH C++)
INCLUDE_DIRECTORIES( "inc" ) # OK, tested and works
LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/lib) # OK, tested and works
ADD_EXECUTABLE(${BINNAME} ${SRCS}) # ?No idea?
TARGET_LINK_LIBRARIES(${BINNAME} myLibrary.lib) # fails
ADD_SUBDIRECTORY( src/Project_01 )
IF( TRUE )
ADD_SUBDIRECTORY( src/Project_02 )
ADD_SUBDIRECTORY( src/Project_03 )
ADD_SUBDIRECTORY( src/Project_04 )
ADD_SUBDIRECTORY( src/Project_05 )
ADD_SUBDIRECTORY( src/Project_06 )
ADD_SUBDIRECTORY( src/Project_07 )
ADD_SUBDIRECTORY( src/Project_08 )
ADD_SUBDIRECTORY( src/Project_09 )
ADD_SUBDIRECTORY( src/Project_10 )
ENDIF()
Each Project has its own CMakeLists.txt which looks like:
cmake_minimum_required (VERSION 2.8)
MESSAGE( STATUS "## ${CMAKE_CURRENT_BINARY_DIR} ##" )
IF ( ${CMAKE_SYSTEM_NAME} MATCHES "Windows" )
### Windows ###
SET( LIB_PROJECT myLibrary )
SET( LIB_SYSTEM )
ELSEIF ( ${CMAKE_SYSTEM_NAME} MATCHES "Linux" )
### Linux ###
SET( LIB_PROJECT myLibrary dl )
SET( LIB_SYSTEM /usr/local/lib )
ENDIF ( ${CMAKE_SYSTEM_NAME} MATCHES "Windows" )
SET( SOURCE_WITHOUT_EXT Project_01 )
SET( PROJECT_EXAMPLE ${SOURCE_WITHOUT_EXT} )
SET( SOURCE_FILES
${SOURCE_WITHOUT_EXT}.cpp
)
FOREACH( Librarys ${LIB_PROJECT} )
MESSAGE("#### Librarys:${Librarys} next will find ...")
SET( SHAREDLIB ${SHAREDLIB}-NOTFOUND )
FIND_LIBRARY ( SHAREDLIB
NAMES ${Librarys}
PATHS ${PROJECT_BINARY_DIR}/lib ${LIB_SYSTEM}
)
MESSAGE("#### SHAREDLIB:${SHAREDLIB}")
IF( SHAREDLIB )
SET( LIBS_ALL ${LIBS_ALL} ${SHAREDLIB} )
SET( SHAREDLIB ${SHAREDLIB}-NOTFOUND )
ENDIF()
MESSAGE("#### ${LIBRARY} found LIBS_ALL${LIBS_ALL}")
ENDFOREACH( Librarys )
ADD_EXECUTABLE( ${PROJECT_EXAMPLE} ${SOURCE_FILES} )
TARGET_LINK_LIBRARIES( ${PROJECT_EXAMPLE} ${LIBS_ALL})
The CMakeLists from these projects are used since long time and therefore considered to be OK. The Problem occured when integrating all projects to one CMake solution.
The error I'm getting is: `"SHAREDLIB:SHAREDLIB-NOTFOUND"
`
There's also a warning:
CMake Warning (dev) at CMakeLists.txt: (TARGET_LINK_LIBRARIES):
Cannot specify link libraries for target "MyLibrary.lib" which is not build by this project.
CMake does not support this but it is used to work accidentally ans is being allowed for compatibility.
Policy CMP0016 is not set: target_link_libraries() reports error if only argument is not a target. Run "cmake --help-policy CMP0016" for policy details. Use the cmake_policy command to set the policy and suppress this warning.
So again, I want to add this library to any project in this solution.
My folders are something like:
C++\
inc\ -> header files
lib\ -> libraries
src\ -> sources with 10 different folders of c++ files
CMake command is:
cmake -G "Visual Studio 10" --build .. -DWIN_64:BOOL=OFF
I'm using CMake 2.8 and VS 2010.
The solution to the problem was the following:
#CMakeLists.txt global:
cmake_minimum_required (VERSION 2.8)
project (Project_Example)
SET(SRC_DIR_PATH C++)
ADD_SUBDIRECTORY( src/Project_01 )
IF( TRUE )
ADD_SUBDIRECTORY( src/Project_02 )
ADD_SUBDIRECTORY( src/Project_03 )
ADD_SUBDIRECTORY( src/Project_04 )
ADD_SUBDIRECTORY( src/Project_05 )
ADD_SUBDIRECTORY( src/Project_06 )
ADD_SUBDIRECTORY( src/Project_07 )
ADD_SUBDIRECTORY( src/Project_08 )
ADD_SUBDIRECTORY( src/Project_09 )
ADD_SUBDIRECTORY( src/Project_10 )
ENDIF()
As you can see, I removed both Include and Link instructions from the golbal CMakeLists. Instead I put them into the appropriate CMakeLists file:
#CMakeLists.txt local (for each project):
cmake_minimum_required (VERSION 2.8)
MESSAGE( STATUS "## ${CMAKE_CURRENT_BINARY_DIR} ##" )
SET(CMAKE_PROJECTNAME Project_01)
SET(PROJECT_BINARY_DIR ../..)
INCLUDE_DIRECTORIES( "${PROJECT_BINARY_DIR}/inc" )
IF ( ${CMAKE_SYSTEM_NAME} MATCHES "Windows" )
### Windows ###
SET( LIB_PROJECT MyLibrary )
SET( LIB_SYSTEM )
ELSEIF ( ${CMAKE_SYSTEM_NAME} MATCHES "Linux" )
### Linux ###
SET( LIB_PROJECT MyLibrary dl )
SET( LIB_SYSTEM /usr/local/lib/ )
ENDIF ( ${CMAKE_SYSTEM_NAME} MATCHES "Windows" )
SET( SOURCE_WITHOUT_EXT Project_01 )
SET( PROJECT_EXAMPLE ${SOURCE_WITHOUT_EXT} )
SET( SOURCE_FILES
${SOURCE_WITHOUT_EXT}.cpp
)
FOREACH( Librarys ${LIB_PROJECT} )
MESSAGE("#### Librarys:${Librarys} next will find ...")
SET( SHAREDLIB ${SHAREDLIB}-NOTFOUND )
FIND_LIBRARY ( SHAREDLIB
NAMES ${Librarys}
PATHS ${PROJECT_BINARY_DIR}/lib ${LIB_SYSTEM}
)
MESSAGE("#### SHAREDLIB:${SHAREDLIB}")
IF( SHAREDLIB )
SET( LIBS_ALL ${LIBS_ALL} ${SHAREDLIB} )
SET( SHAREDLIB ${SHAREDLIB}-NOTFOUND )
ENDIF()
MESSAGE("#### ${LIBRARY} found LIBS_ALL${LIBS_ALL}")
ENDFOREACH( Librarys )
ADD_EXECUTABLE( ${PROJECT_EXAMPLE} ${SOURCE_FILES} )
TARGET_LINK_LIBRARIES( ${PROJECT_EXAMPLE} ${LIBS_ALL})
Although this works now, I'm still asking myself what if I had not 10 but 100 projects? This would be really pain in the ass to modify each CMakeLists individually.
Related
I need to include some generated files (for example output from go-swagger) in a binary. Without bazel you can do that using go:generate in combination with go:embed:
package demo
//go:generate swagger generate spec -w . -o ./openapi.json
import "embed"
// Content contains openapi.json file generated via go-swagger from spec
//go:embed openapi.json
var Content embed.FS
I am trying to do the same thing with bazel. As a simple test I have have this BUILD.bazel file:
genrule(
name = "hellodata",
srcs = ["hello.go"],
outs = ["hello.txt"],
cmd = "cat $(SRCS) | tr A-Za-z N-ZA-Mn-za-m > $#",
)
go_library(
name = "hello",
srcs = ["hello.go"],
importpath = "wiggy.net/hello",
visibility = ["//visibility:public"],
embedsrcs = [":hellodata"],
)
with hello.go looking like this:
package hello
import (
_ "embed"
"io"
)
//go:embed hello.txt
var greeting []byte
func Hello(out io.Writer) error {
_, err := out.Write(greeting)
return err
}
The intention here is to have Hello output the rot13 of it's own source. When I try to compile this it successfully generates hello.txt (located in bazel-out/darwin_arm64-fastbuild/bin/hello.txt), but the compiler can not find it:
❯ bazel build //...
INFO: Analyzed 5 targets (0 packages loaded, 0 targets configured).
INFO: Found 5 targets...
ERROR: /Users/wichert/Hack/bzl/BUILD.bazel:14:11: GoCompilePkg hello.a failed: (Exit 1): builder failed: error executing command bazel-out/host/bin/external/go_sdk/builder compilepkg -sdk external/go_sdk -installsuffix darwin_arm64 -src hello.go -embedsrc bazel-out/darwin_arm64-fastbuild/bin/hello.txt -importpath wiggy.net/hello ... (remaining 12 argument(s) skipped)
Use --sandbox_debug to see verbose messages from the sandbox
compilepkg: /private/var/tmp/_bazel_wichert/e7573342ee9452df4c3dfa671d399a16/sandbox/darwin-sandbox/76/execroot/__main__/hello.go:8:12: could not embed hello.txt: no matching files found
INFO: Elapsed time: 0,112s, Critical Path: 0,04s
INFO: 2 processes: 2 internal.
FAILED: Build did NOT complete successfully
I noticed -embedsrc bazel-out/darwin_arm64-fastbuild/bin/hello.txt in the command line for the failing action in your question, so as a hunch I tried the equivalent on my machine:
//go:embed bazel-out/k8-fastbuild/bin/hello.txt
var greeting []byte
And that seemed to work.
This is not so great because configuration information gets embedded in the source files (indeed, on your mac machine it's darwin_arm64-fastbuild and on my linux machine it's k8-fastbuild), so now your source code is artificially platform dependent.
It looks like this feature is relatively new (https://github.com/bazelbuild/rules_go/issues/2775, https://github.com/bazelbuild/rules_go/issues/2986). I would file an issue with rules_go about this.
There also appears to be go_embed_data which might behave differently:
https://github.com/bazelbuild/rules_go/blob/master/docs/go/extras/extras.md#go_embed_data
To answer my own question: the trick is to use genrule to generate the file(s) to be embedded, and then use go_embed_data to embed them. A work BUILD.bazel looks like this:
genrule(
name = "hellodata",
srcs = ["hello.go"],
outs = ["hello.txt"],
cmd = "cat $(SRCS) | tr A-Za-z N-ZA-Mn-za-m > $#",
)
go_embed_data(
name = "hello_embed",
src = ":hellodata",
package = "hello",
var = "greeting",
)
go_library(
name = "hello",
srcs = [
"hello.go",
":hello_embed",
],
importpath = "wiggy.net/hello",
visibility = ["//visibility:public"],
)
I have the following bazel BUILD configured to
gazelle(name = "gazelle")
go_embed_data(
name = "static_files",
srcs = glob(["static/**/*"]),
package = "main",
var = "staticFS",
)
go_library(
name = "kmdr_lib",
srcs = ["main.go"],
importpath = "github.com/myorg/myrepo",
visibility = ["//visibility:private"],
deps = [
"//api",
"//cmd",
],
)
With the following embed tag
package main
import (
"embed"
"github.com/myorg/myrepo/api"
"github.com/myorg/myrepo/cmd"
)
//go:embed static/*
var staticFS embed.FS
func main() {
api.StaticFS = staticFS
cmd.Execute()
}
However, when running...
bazel run //:gazelle
bazel build //...
I receive the following error that the static files tagged in the go main package could not be matched.
ERROR: GoCompilePkg kmdr_osx_amd64.a failed: (Exit 1): builder failed: error executing command bazel-out/host/bin/external/go_sdk/builder compilepkg -sdk external/go_sdk -installsuffix darwin_amd64 -src main.go -arc ... (remaining 17 argument(s) skipped)
Use --sandbox_debug to see verbose messages from the sandbox
compilepkg: baf0dff8fcdeaf74ff5ba5ff8921e77f/sandbox/linux-sandbox/425/execroot/__main__/main.go:22:12: could not embed static/*: no matching files found
INFO: Elapsed time: 1.249s, Critical Path: 0.15s
INFO: 5 processes: 5 internal.
FAILED: Build did NOT complete successfully
The go_embed_data documentation doesn't give much details on how to use the library. I've also tried referencing the :static_files in the go_library srcs however, gazelle rewrites that.
bazel will rewrite the go_library if I reference go_emebed_data in the library srcs
go_embed_data generates a .go file that contains data from a file or a list of files. It should be consumed in the srcs list of one of the core go rules.
go_library(
name = "kmdr_lib",
srcs = ["main.go", ":static_files"],
importpath = "github.com/myorg/myrepo",
visibility = ["//visibility:private"],
deps = [
"//api",
"//cmd",
],
)
EDIT:
go build will parse the tag and embed the data as expected
It looks like go_embed_data is not the right method.
There was a PR made to address this issue https://github.com/bazelbuild/rules_go/pull/2806#issuecomment-784690934
Adding embedsrcs to your go_library will respect the go:embed directive
I managed to send a message from an MQ Client to a MQ Server. In the MQ Client I amqsputc [queue_local] [name_qmgr] and after typing the message it return Sample AMQSPUT0 end which means it was sent properly. But when I try to see the message in the MQ Server with amqsbcg [queue_local] [name_qmgr] it throws me an error message:
Sample AMQSGET0 start
MQCONNX ended with reason code 2058
This error appears when the queue manager doesn't exist or when the name is misspelled, but this is not the case.
When I verify the local queue it shows CURDEPTH(1), this means that there is one message on the queue(it was delivered). But I don't know why it doesn't allow me to get the message. In the queue manager error file it only shows something like:
the channel AMQ.... connection ended
I checked the channel I configured for this test:
AMQ8414: Display Channel details.
CHANNEL(A03ZCIWAS) CHLTYPE(SVRCONN)
ALTDATE(2017-09-07) ALTTIME(00.35.17)
CERTLABL( ) COMPHDR(NONE)
COMPMSG(NONE)
DESCR(Server-connection to ...)
DISCINT(0) HBINT(300)
KAINT(AUTO) MAXINST(100)
MAXINSTC(90) MAXMSGL(4194304)
MCAUSER(nobody) MONCHL(QMGR)
RCVDATA( ) RCVEXIT( )
SCYDATA( ) SCYEXIT( )
SENDDATA( ) SENDEXIT( )
SHARECNV(10) SSLCAUTH(REQUIRED)
SSLCIPH( ) SSLPEER( )
TRPTYPE(TCP)
AMQ8414: Display Channel details.
CHANNEL(A03ZCIWAS) CHLTYPE(CLNTCONN)
AFFINITY(PREFERRED) ALTDATE(2017-09-07)
ALTTIME(02.40.42) CERTLABL( )
CLNTWGHT(0) COMPHDR(NONE)
COMPMSG(NONE) CONNAME(XX.XX.XX.XX)
DEFRECON(NO)
DESCR(Client connection to ....)
HBINT(300) KAINT(AUTO)
LOCLADDR( ) MAXMSGL(4194304)
MODENAME( ) PASSWORD( )
QMNAME(AEDMQ03A) RCVDATA( )
RCVEXIT( ) SCYDATA( )
SCYEXIT( ) SENDDATA( )
SENDEXIT( ) SHARECNV(10)
SSLCIPH( ) SSLPEER( )
TPNAME( ) TRPTYPE(TCP)
USERID( )
The CONNAME(xx.xx.xx.xx) is the right IP adress for the MQServer and the variable MQSERVER is set like:
MQSERVER=[channel_svrconn]/tcp/'ip_adress_MQServer(1414)'
The port is also fine.
The output you provide indicates you are executing amqsget not amqsbcgc.
I note that your question mentions amqsbcg not amqsbcgc. The c at the end of the sample name indicates it is the client version of the program.
amqsbcg = Server Binding version
amqsbcgc = Client version
If you execute either amqsget or amqsbcg and specify a queue manager that is not local on the same server you will receive a 2058.
Solution is to use amqsgetc or amqsbcgc instead of amqsget or amqsbcg
I am writing the auto-build system for the one complicated Qt5 program.
Some of it's C++ sources contains special markers and need to be processed by the external utility.
So i decide to write a custom prebuild step in qmake project like this:
!build_pass {
win32 {
for( src, SOURCES ) {
system("findstr \"MY_CUSTOM_MARKER\" $$src"):system( MyExternalUtil $$src )
}
}
}
But first system command always return success, i.e. all of my sources will be processed!
However, official Qt documentation say they should not.
So my question is: why such system command always returns 0?
P.S. I tried it in the Windows command prompt: findstr properly set %errorlevel% to the 1 when specified text was not found.
P.P.S Here is the workaround(just use other version of system):
!build_pass {
win32 {
for( SRC_PATH, SOURCES ) {
FULL_SRC_PATH = \"$$PWD/$$SRC_PATH\"
FULL_SRC_PATH = $$replace( FULL_SRC_PATH, /, \ )
FIND_RES = $$system( findstr \"MY_CUSTOM_MARKER\" $$FULL_SRC_PATH )
!isEmpty( FIND_RES ) {
message( Processing $$SRC_PATH... )
system( MyExternalUtil $$FULL_SRC_PATH )
}
}
}
}
defineTest(systemWrapper) {
ret = $$system($${ARGS} 2> /dev/null; echo $?)
equals(ret, 0):return(true)
return(false)
}
I think it a big limitation that you can't use "newTextField" in corona simulator, I actually need to build the app and install it on my device to see if it's working.
The following code for some reason not working for me, and I don't know how to debug it.
I simply want to save "players name"
local function textListener( event )
if ( event.phase == "began" ) then
-- user begins editing text field
print( event.text )
myGameSettings.playerName = event.text
saveSettings()
elseif ( event.phase == "ended" ) then
-- text field loses focus
myGameSettings.playerName = event.text
saveSettings()
elseif ( event.phase == "ended" or event.phase == "submitted" ) then
myGameSettings.playerName = event.text
saveSettings()
-- do something with defaultField's text
elseif ( event.phase == "editing" ) then
print( event.newCharacters )
print( event.oldText )
print( event.startPosition )
print( event.text )
end
end
local playerName = native.newTextField( centerX, display.contentCenterY-100, display.contentWidth, 50 )
display.newText("Choose a name", 20, playerName.y-70, native.systemFont)
playerName:addEventListener( "userInput", textListener )
It appears to be supported only in the Enterprise version.
Is your problem that it isn't working in the Simulator? Because they don't work on the Windows PC simulator but they work in the Mac simulator. I develop on Mac and PC and can use them perfectly on Mac but not on PC. I'm also no on the Enterprise edition but am on the free edition.
When I'm working on my PC how I debug is to hook my device up to the computer and print out the debug log as it will print any errors (I obviously can only use Android devices hooked up to my PC).
First of all the native.newTextField does not display on window machine simulator. you need to build it on device for testing. But you can debug it on simulator though.
Use below code for debug on simulator.
Note: the textField area is not visible but when you click on it(Assuming text field position), will show you the textfield with blue rectangle border.
-- Hide the status bar
display.setStatusBar( display.HiddenStatusBar )
-- Set the background to white
display.setDefault( "background", 255, 255, 255 )
-- Require the widget & storyboard libraries
local widget = require( "widget" )
local function textListener( event )
if ( event.phase == "began" ) then
print( event.text )
elseif ( event.phase == "ended" or event.phase == "submitted" ) then
-- do something with defaultField's text
elseif ( event.phase == "editing" ) then
print("in move")
print( event.newCharacters )
print( event.oldText )
print( event.startPosition )
print( event.text )
end
end
local playerName = native.newTextField( 300, 300, 400, 50 )
local a = display.newText("Choose a name", 20, playerName.y-70, native.systemFont)
a.x=100
a.y = playerName.y-70
a:setTextColor(0,0,0)
playerName:addEventListener( "userInput", textListener )